Performance as a Product Feature: Reaching ~95 Lighthouse and Real SEO Gains
The fastest way to get stuck in performance work is to treat it like a “tech debt cleanup.”
Performance improves when you treat it like:
- a product requirement
- a release gate
- a continuous feedback loop
We ran a performance initiative that pushed Lighthouse into the ~95 range on key pages and - more importantly - moved real Core Web Vitals in the right direction. We also saw SEO improvements that tracked with those CWV wins.
This post is the workflow and the specific levers that actually moved the needle.
Step 0: measure production, not vibes
Before you optimize:
- run Lighthouse in mobile mode
- test on real devices if possible
- use WebPageTest for network + CPU realism
- pull real-user metrics (CrUX / RUM if you have it)
The metric that matters is user experience, not a single Lighthouse run on your laptop.
We anchored on:
- LCP (largest contentful paint)
- CLS (layout stability)
- INP (interaction responsiveness)
- TTFB (server responsiveness)
Lighthouse is useful as a lab tool, but real-user metrics decide whether you’ve actually improved the product.
Step 1: set budgets (or you’ll regress immediately)
Performance work is fragile. If you don’t enforce it, it slowly decays.
We added budgets for:
- JS total size (and per-route budgets)
- number of third-party scripts
- image weight above the fold
- CWV thresholds (lab + RUM)
Budgets are not about perfection. They’re about making trade-offs explicit:
“This feature costs 40KB of JS. Is it worth it?”
Step 2: use a repeatable profiling workflow
When a page is slow, guesswork wastes time.
Our workflow:
- Network waterfall: what blocks first paint? (fonts, CSS, JS, API)
- Main thread: long tasks, script evaluation, hydration cost
- Rendering: layout thrash, CLS sources, expensive paints
- Bundle: which deps are heavy, which chunks are loaded when
We documented this as a checklist so performance wasn’t “one expert’s magic.”
The big lever: hydration and JavaScript cost
The most consistent path to ~95 Lighthouse on content-heavy pages is:
- render as much as possible on the server
- ship less JS
- hydrate only what must be interactive
In practical terms:
- remove client-side frameworks from pages that don’t need them
- use islands/partial hydration for interactive widgets
- delay non-critical hydration until after first paint
If your app is an SPA, you can still apply the same principle:
- route-level code splitting
- avoid loading admin-only code for public pages
- avoid “framework + design system + analytics” booting before content is visible
Images: the second lever that rarely disappoints
We got reliable gains from an image strategy that was boring but consistent:
- responsive images (
srcset/sizes) - modern formats (AVIF/WebP)
- strict width/height to prevent CLS
- lazy loading for below-the-fold
- preload the hero image only when it truly is the LCP element
Common pitfall:
- preloading too many assets and competing with your own critical requests
Fonts and CLS: polish that boosts perceived quality
Two quick wins that users notice immediately:
- prevent layout shift from fonts (use
font-display: swap, stable fallbacks) - reserve space for content that arrives later (images, ads, widgets)
CLS is a trust metric. Pages that “jump around” feel broken even when they load fast.
Third-party scripts: treat them like dependencies with a cost
Third-party scripts are often the silent performance budget killers:
- analytics tags
- chat widgets
- A/B testing SDKs
We did three things:
- removed what wasn’t pulling its weight
- deferred what wasn’t needed for initial render
- isolated what was expensive (load only on pages that truly need it)
If you’ve never done a “third-party inventory,” do it once - you’ll be shocked.
Indexing implications: performance helps, but doesn’t replace SEO fundamentals
Performance improvements correlated with SEO gains for us, but the relationship is not magic:
- CWV is one signal among many
- content quality and relevance still dominate
Performance work helped SEO most when paired with:
- correct headings and semantics
- canonical URLs
- clean sitemap
- proper metadata (title/description, open graph)
- avoiding duplicate content and infinite parameterized URLs
In other words: fast pages are easier to rank, but only if they’re also worth ranking.
A (simplified) before/after story
Our baseline looked like:
- Lighthouse: “good days” in the 60–70s
- LCP in the “noticeably slow” range on mid-tier mobile
- JS bundle doing too much too early
- images larger than they needed to be
After the initiative:
- Lighthouse consistently in the ~90–95 range on key pages
- LCP became predictable and stable
- interaction responsiveness improved because we reduced main-thread contention
The exact numbers will differ for your site, but the sequence of improvements is repeatable.
What made the improvements stick
- budgets in CI
- performance review as part of feature PRs for critical pages
- dashboards with trend lines (not one-off scores)
- a shared profiling workflow so anyone could contribute fixes
A checklist you can steal
- Measure production and real-user metrics
- Set performance budgets (JS, images, third-party, CWV)
- Profile with a consistent workflow (network → main thread → rendering → bundle)
- Reduce hydration/JS cost (SSR/islands/code splitting)
- Fix images (responsive, formats, preload only the LCP)
- Fix CLS (reserve space, stable fonts)
- Audit third-party scripts
- Pair performance with SEO basics (semantics, sitemap, canonical, metadata)
- Enforce budgets to prevent regressions
Performance work is most satisfying when it stops being “a sprint” and becomes a product capability. The score is a nice trophy, but the real win is a site that feels fast for real users and stays that way.