PERFORMANCE
Performance13 min read

How Claude + Next.js Helped Us Achieve 99/100 Lighthouse Scores Automatically

DS

De Studio

Web Development Studio

May 25, 2026
13 min read

A 99/100 Lighthouse score is not luck — it is a system. Here is the exact process we used at De Studio: combining Claude AI for intelligent code review and problem diagnosis with Next.js 16's built-in performance architecture to hit near-perfect scores on Performance, SEO, Accessibility, and Best Practices — and keep them there automatically.

Why 99/100 Is Worth Chasing

Lighthouse is Google's open-source tool for measuring the quality of a web page across four categories: Performance, Accessibility, Best Practices, and SEO. Each category scores from 0 to 100. Most production websites score somewhere between 60 and 85. A score above 90 is considered good. A score of 99 or 100 is exceptional — and it matters more than most business owners realise.

Google has confirmed that Core Web Vitals — the performance metrics that drive Lighthouse's Performance score — are a ranking factor in search results. A slow website does not just frustrate users. It ranks lower, drives up bounce rates, and loses organic traffic to faster competitors. The performance gap compounds over time.

Beyond SEO, a high Lighthouse score is a proxy for everything users care about: fast load times, readable content, accessible design, and secure connections. A 99/100 score means your site loads fast on a slow mobile connection in rural India, works correctly with a screen reader, passes every modern security check, and gives Google exactly the signals it needs to rank you confidently.

At De Studio, hitting 99/100 across all four Lighthouse categories on our own website was a deliberate project — not a side effect of good development. This article documents exactly how we got there: the tools, the techniques, the mistakes we made, and how Claude AI accelerated every stage of the process.

Where We Started — and What Was Broken

Before the optimisation sprint began, our Lighthouse scores were respectable but not exceptional:

Performance: 84 — reasonable, but with clear headroom Accessibility: 79 — several real violations that needed fixing Best Practices: 92 — close, but a few issues dragging it down SEO: 91 — one specific failure that proved surprisingly tricky to fix

Each score had specific, identifiable causes. Diagnosing them accurately was the first challenge — and it is where Claude AI provided immediate value.

The Performance Drag The 84 Performance score was caused by a combination of factors that are common in Next.js projects built under time pressure: render-blocking third-party scripts, unoptimised font loading, a large hero image without proper dimensions, and several components loading heavy animation libraries eagerly rather than lazily. Each issue individually was small. Together, they were pushing Largest Contentful Paint (LCP) — the time until the main visible element loads — past the 2.5-second threshold that Google considers 'good'.

The Accessibility Failures The 79 Accessibility score had three root causes. First, the interactive dot buttons in our Hero section had insufficient colour contrast (the inactive dots were white at 15% opacity against a dark background — well below the 3:1 minimum ratio). Second, several icon-only buttons in the footer had no accessible labels, making them meaningless to screen reader users. Third, the heading hierarchy in the footer and contact form section jumped from h1 directly to h4, which breaks the document outline that screen readers use to navigate.

The SEO Mystery The SEO score of 91 had a single cause that took longer to diagnose than expected: the meta description was present in the HTML but not in the initial HTTP response head. Next.js 16 introduced 'streaming metadata' — for dynamically rendered pages, metadata from the async generateMetadata() function is streamed to the browser after the initial HTML is sent, not included in the head of the first response. Lighthouse reads the initial response head, finds no description, and marks it as missing. Google's mobile crawler has the same behaviour.

How We Used Claude to Diagnose and Fix Issues 3x Faster

Claude was not a magic button that fixed everything automatically. It was a highly capable collaborator that compressed every diagnostic and problem-solving step that would normally require hours of Stack Overflow searches, documentation reading, and trial-and-error into focused, accurate conversations.

Diagnosing the Streaming Metadata Issue The SEO failure was the best example of Claude's diagnostic value. The symptom was clear — Lighthouse reported 'Document does not have a meta description' — but the cause was not obvious, because curling the live page showed the description clearly in the HTML. The contradiction (description visible in HTML but Lighthouse says it is missing) was confusing.

When we described the symptom to Claude — including the Next.js version, the fact that we were using generateMetadata() in the layout, and the curl output showing the description at byte position 108,000 rather than in the head — Claude identified the cause immediately: streaming metadata. It explained that in Next.js 16, async metadata is streamed separately from the initial HTML head for dynamically rendered pages, and that Lighthouse's mobile crawler reads the initial head before streaming completes. It then pointed us directly to the htmlLimitedBots configuration option in next.config.ts and explained exactly what setting to apply.

What would have been a multi-hour debugging session — reading Next.js changelog entries, testing different configurations, comparing curl output to browser DevTools — took under fifteen minutes.

Fixing Accessibility Violations For each accessibility violation, Claude's approach was to understand the WCAG criteria behind the failure before suggesting a fix. Rather than just saying 'increase the opacity', it explained that the WCAG 2.5.5 minimum touch target requirement of 24x24 CSS pixels was being violated, why the visual dot needed to be separate from the touch area, and how to structure the button wrapper correctly so that the visible element and the interactive element had different sizes without overlapping hit areas.

The specific solution it provided — a 24x24px button wrapper using w-6 h-6 with gap-0 to prevent overlapping, containing a smaller visual dot that changes shape on active state — was more elegant than our initial approach of using negative margins, which would have caused overlapping touch targets on adjacent buttons.

Code Review as a First Pass Throughout the optimisation process, we used Claude to review component code before making changes, asking it to identify any issues that might affect Performance, Accessibility, Best Practices, or SEO scores. This 'pre-flight check' approach caught issues we had not yet noticed — including an aria-hidden attribute missing from decorative SVG icons in the footer, which was causing screen readers to announce meaningless path descriptions.

The Performance Optimisations — Every Point Explained

Pushing Performance from 84 to 99 required fixing every category of drag on the page load sequence. Here is each optimisation, what it fixed, and how much it moved the score.

Image Optimisation with Next.js Image Component The hero section was loading a large background image without specified dimensions, causing Cumulative Layout Shift (CLS) as the page reflowed around it. We replaced the raw img tag with Next.js's Image component, which automatically generates WebP versions, serves the correct size for each device, lazy-loads off-screen images, and eliminates CLS by reserving the correct space before the image loads. This single change moved our CLS score from 0.14 (needs improvement) to 0.02 (excellent) and reduced hero image payload by over 60%.

Font Loading Strategy We were loading Google Fonts via a standard link tag in the head, which blocks rendering until the font file downloads. Switching to Next.js's built-in font optimisation (next/font/google) solved this: the font CSS is inlined into the page HTML, the font file is served from the same domain as the site (no DNS lookup for fonts.gstatic.com), and font-display: swap ensures text is visible during font load rather than invisible. Cumulative page weight from font loading dropped from 42KB to 0KB (the font is now self-hosted by Vercel).

Code Splitting and Lazy Loading The animation library (Motion) was being imported at the top level of several components that were visible above the fold. This meant the animation JavaScript was being downloaded and parsed as part of the critical rendering path, blocking First Contentful Paint (FCP). We audited every component for animation imports and moved heavy animations to dynamic imports with { ssr: false } where they were below the fold or only triggered on interaction. This reduced our Total Blocking Time (TBT) from 180ms to 40ms.

Eliminating Render-Blocking Scripts A third-party analytics script was being loaded synchronously in the document head, blocking HTML parsing while it downloaded. Moving it to load with the async attribute — ensuring it does not block rendering — and deferring it until after the interactive event reduced Time to Interactive (TTI) significantly. For scripts that are not critical to initial page display, async and defer loading should always be the default.

Server-Side Rendering and ISR Next.js's Incremental Static Regeneration (ISR) means pages are pre-rendered at build time and served from Vercel's edge CDN — not computed on a server for every request. The Time to First Byte (TTFB) for a cached ISR page served from a nearby Vercel edge node is typically under 50ms globally. For comparison, a WordPress page on shared hosting with no caching can have a TTFB over 800ms. This architectural advantage accounts for a significant portion of the performance score difference between Next.js and traditional CMS platforms.

Accessibility: From 79 to 100

Accessibility is the Lighthouse category that most studios treat as optional — and where most scores suffer as a result. Going from 79 to 100 required fixing every WCAG violation methodically. Here is the complete list of what we fixed and how.

Colour Contrast Failures The hero section's inactive dot buttons had a contrast ratio of approximately 1.8:1 (white at 15% opacity on a dark background). WCAG 2.1 requires a minimum of 3:1 for UI components and graphical objects. The fix was straightforward: increase opacity from 15% to 50% (bg-white/50 in Tailwind). This raised the contrast ratio above 3:1 while maintaining the visual design intent of an inactive/active state difference.

Missing Button Labels Four social media icon buttons in the footer had no accessible labels — they contained only SVG icons with no text. A screen reader user hearing 'button, button, button, button' with no context cannot understand the function of any of them. We added aria-label attributes to each anchor element ('Follow De Studio on LinkedIn', 'Follow De Studio on Twitter' etc.) and added aria-hidden='true' to the SVG icons themselves, preventing the screen reader from announcing path descriptions.

Heading Hierarchy Fix The footer had h4 elements for section headings ('Navigation', 'Get In Touch') without any preceding h2 or h3 in those regions. Lighthouse's accessibility audit and WCAG both require a logical heading hierarchy — you cannot jump from h1 to h4. We changed these to h3 elements, which fit correctly into the document outline. Similarly, the contact form success state used an h4 for the 'Message Sent!' heading, which we updated to h3.

Touch Target Size The hero dot buttons had a visual size of 8x8px (w-2 h-2) with no padding, giving them an effective touch target well below the WCAG 2.5.5 minimum of 24x24px. On mobile, a user attempting to tap these dots was almost certainly activating the wrong one. The fix: wrap each visual dot in a transparent 24x24px button element (w-6 h-6 in Tailwind), which provides the minimum touch area while keeping the visual dot small. Using gap-0 on the container ensured adjacent buttons do not have overlapping hit areas.

Semantic HTML Audit Claude flagged several instances where div elements with onClick handlers were being used where button elements were semantically correct. Every interactive element that triggers an action (not navigation) should be a button element — it is keyboard focusable by default, supports Enter and Space key activation, and is announced correctly to screen readers without requiring custom ARIA attributes. Replacing div onClick handlers with proper button elements is one of the highest-impact accessibility fixes available in React codebases.

Building the Automated Quality Gate

Fixing scores once is not enough. The goal is to prevent them from regressing as the codebase evolves. We built an automated quality gate that makes it structurally difficult to ship code that drops any Lighthouse category below 95.

CI/CD Integration with axe-core Axe-core is the accessibility scanning engine that powers Lighthouse's accessibility audit. It is available as a Node.js package that integrates directly into testing frameworks. We added an axe-core scan to our GitHub Actions CI workflow, configured to run against a preview deployment on every pull request. If the scan returns any critical or serious violations, the CI check fails and the PR cannot be merged. Accessibility violations are caught before they reach production — not discovered by a user with a screen reader after they ship.

Lighthouse CI in the Pipeline Lighthouse CI (LHCI) is the command-line version of Lighthouse, designed for automation. We configured it to run a full Lighthouse audit against each preview deployment as part of the CI pipeline. Thresholds are set in the lighthouserc.js config file:

Performance: minimum 90 (fail below this) Accessibility: minimum 95 (fail below this) Best Practices: minimum 90 (fail below this) SEO: minimum 95 (fail below this)

If any category drops below its threshold, the GitHub check fails with the specific failing audits listed in the output. The developer sees exactly what broke and why, before the code merges.

TypeScript as a Quality Gate Strict TypeScript configuration catches a category of errors that contribute to Best Practices failures — specifically, runtime JavaScript errors that Lighthouse detects by running the page in a real browser. Enabling strict: true in tsconfig.json and treating TypeScript errors as build failures (which Next.js does by default) means many classes of runtime errors are caught at compile time.

Automated Dependency Updates Outdated dependencies are a common source of Best Practices score drag — particularly outdated packages with known security vulnerabilities that browsers flag in DevTools. Dependabot, configured to automatically open PRs for dependency updates on a weekly schedule, keeps the dependency tree current without manual oversight. Each Dependabot PR runs the full Lighthouse CI pipeline before merging, ensuring an update does not introduce a regression.

The htmlLimitedBots Configuration The SEO fix that solved the streaming metadata issue — htmlLimitedBots: /.*/ in next.config.ts — is the one configuration change that most Next.js 16 projects need to make but almost none have made. This single line disables streaming metadata for all user agents, ensuring that every HTTP response includes the full title, description, OG tags, and canonical URL in the initial HTML head — exactly where Google, Lighthouse, LinkedIn, and every other crawler expects to find them.

The Final Scores and What They Mean for Your Business

After completing the full optimisation process, our Lighthouse scores on mobile (the harder target — mobile scores are always lower than desktop due to CPU throttling in the audit) settled at:

Performance: 99 Accessibility: 100 Best Practices: 100 SEO: 100

Desktop scores across all four categories: 100.

These scores are maintained automatically by the quality gate in our CI/CD pipeline. New features, content updates, and dependency changes all pass through Lighthouse CI before reaching production. Regressions are caught in minutes, not weeks.

What This Means for SEO Core Web Vitals are a confirmed Google ranking factor. A site with LCP under 2.5 seconds, CLS under 0.1, and INP under 200ms gets a performance ranking boost. More importantly, a fast site reduces bounce rate — users who land on a page that loads in 1.2 seconds stay longer than those on a page that loads in 3.5 seconds. Lower bounce rate is itself a positive ranking signal.

What This Means for Conversions Amazon's research found that every 100ms of load time improvement correlated with a 1% increase in revenue. At the scale of a marketing website, a Performance score improvement from 65 to 99 — roughly a 1.5 to 1.2 second improvement in LCP — can meaningfully move conversion rates.

What This Means for Accessibility and Legal Compliance A 100 Accessibility score indicates compliance with WCAG 2.1 AA — the standard required by the European Accessibility Act (effective 2025), the US ADA, and equivalent legislation in Australia, Canada, and the UK. Accessibility compliance is not just good practice in 2026. It is a legal requirement for many businesses and a commercial advantage for all of them.

How to Replicate This for Your Website The complete process we followed is reproducible for any Next.js project. Run a Lighthouse audit on your current site (free, via Chrome DevTools or PageSpeed Insights). Identify your lowest-scoring category. Use Claude to diagnose the specific failing audits — describe the symptom, share the relevant code, and work through the fix. Add Lighthouse CI to your GitHub Actions pipeline. Set thresholds. Maintain.

The tools are free. The process is documented. The results are measurable. The only variable is whether you treat Lighthouse scores as a vanity metric or as the business-critical indicators they actually are.

At De Studio, every website we build ships with a Lighthouse CI pipeline configured from day one. Our clients' sites start at 95+ across all four categories and are maintained there automatically — because a website that degrades over time is a liability, and one that holds its quality automatically is an asset.

TagsPerformanceDesignDe Studio
Keep Reading

Related Posts

CMS
CMS

May 27, 2026

Webflow vs Sanity: Which Platform Wins for Automation in 2026?

Webflow and Sanity are both powerful platforms — but they automate completely different things. Choosing the wrong one for your project means rebuilding in 18 months. This is the definitive side-by-side comparison of their automation capabilities, limitations, and the exact scenarios where each one wins.

Read Post
UI/UX
UI/UX

May 26, 2026

Claude Meets Figma: How AI Is Completely Reforming UI/UX Design in 2026

Figma and Claude AI are now deeply connected — and the UI/UX design workflow will never be the same. From generating entire design systems in minutes to automatically auditing accessibility and converting designs directly to production-ready Next.js code, here is everything that has changed and what it means for designers, developers, and businesses.

Read Post
AUTOMATION
Automation

May 24, 2026

The Automated Lead Machine: How to Turn Your Website into a 24/7 Sales Engine in 2026

Most business websites collect dust between 9 AM and 5 PM and go completely dark overnight. The best-performing websites in 2026 work around the clock — qualifying leads, answering questions, booking calls, and nurturing prospects automatically. Here is how to build one.

Read Post
Let's Work Together

Ready To Transform Your Digital Presence

Let's build something remarkable together. Book a free discovery call and find out how we can help you design and develop a product your users will love.