Website performance optimization is the discipline of making web pages faster, lighter, and more responsiveacross all devices and connection types — through coordinated improvements to TTFB, FCP, LCP, CLS, INP, total byte weight, and main-thread work. It is not one technique; it's a stack of techniques applied in priority order, server tier first and stability last.
Think of performance optimization like tuning a car. The engine (server tier) sets the upper bound on how fast you can ever go. The transmission (critical render path) decides how quickly that power reaches the wheels. The body weight (asset size) and the suspension (runtime + stability) decide how the ride feels. Skip a layer and the whole car still feels slow.
Three independent forces make performance a first-class concern in 2026:
Optimize from the bottom of the stack up. A fast front end on a slow server still feels slow, and a stable layout on a render-blocked page still fails LCP. Tackle the layers in this order:
Edge caching, CDN distribution, database query tuning, response compression (Brotli or gzip), and edge-rendered pages. Every page on the site inherits TTFB — fix it first or every other improvement is bottlenecked. Target: TTFB < 800 ms at the 75th percentile.
Inline critical CSS, defer non-critical JavaScript, eliminate render-blocking resources, preload the LCP image. The browser can't paint until it has parsed every render-blocking resource — shrink that set to the minimum.
Modern image formats (AVIF, WebP), responsive srcset, font subsetting and font-display: swap, JavaScript minification, dead-code elimination, CSS purging. The goal is to ship fewer bytes, not just compressed bytes.
Code splitting, route-level lazy loading, breaking up long tasks, moving heavy work to Web Workers, virtualizing long lists. INP is the metric that surfaces real interaction lag — and it's almost always caused by main-thread JavaScript.
Set explicit width and height on every image and video, reserve space for ads and embeds, preload custom fonts and tune fallback metrics with size-adjust, avoid injecting content above the fold after first paint.
Performance budgets enforced in CI, real-user monitoring (RUM), 28-day field-data review in Google Search Console, periodic crawler scans. Optimization without monitoring is a one-time win that erodes silently.
A practical sequence for a typical commerce or content site that's failing Core Web Vitals. The order matters — earlier wins multiply later ones.
# Week 1 — Server tier (highest leverage)
Add edge cache for static + cacheable dynamic routes (60s SWR).
Enable Brotli compression at the edge.
Move the origin closer (multi-region or edge functions).
Expected: TTFB 1.4 s --> 250 ms. LCP impact: -1.0 s site-wide.
# Week 2 — Critical render path
Inline critical CSS for the top fold.
Defer all non-critical JS (analytics, chat, ads).
Preload the hero image with fetchpriority="high".
Expected: FCP -0.6 s, LCP -0.8 s.
# Week 3 — Asset optimization
Convert hero + product images to AVIF with WebP fallback.
Add responsive srcset so mobile gets mobile-sized images.
Subset and self-host the brand font; preload one weight.
Expected: image bytes -55%, font reflow eliminated.
# Week 4 — Runtime / INP
Code-split route bundles (per-page chunks).
Break long tasks > 50 ms with scheduler.yield() or setTimeout.
Move heavy parsing (search index, JSON transforms) to a Web Worker.
Expected: INP 320 ms --> 160 ms.
# Week 5 — Stability / CLS
Add width + height to every <img> and <video>.
Wrap ad slots in fixed-size containers.
Set font fallback metrics with size-adjust.
Expected: CLS 0.28 --> 0.04.
# Week 6 — Lock in the win
Add a performance budget to CI (LCP < 2.5 s, JS < 200 KB).
Wire up RUM (web-vitals.js + your analytics endpoint).
Schedule a monthly Greadme crawler scan.
Expected: regressions caught in PR, not in Search Console.The teaching point: this sprint front-loads the changes that affect every page (server, render path) before touching per-page concerns (assets, runtime). A team that starts with image compression in Week 1 misses the multiplier effect of fixing TTFB first.
Use lab tools to iterate during development and field data to declare success. They are complementary, not interchangeable.
The single highest-leverage change. Even a 60-second cache on a hot product page collapses TTFB and removes 90% of origin load. Use stale-while-revalidate so users get a cached response while a background revalidation runs.
AVIF or WebP at the right pixel dimensions for the device cuts image payload by 50–70% versus JPEG/PNG. The image build tool sharp covers this for most pipelines; modern frameworks emit responsive srcset automatically.
<picture>
<source type="image/avif" srcset="/hero-480.avif 480w, /hero-1024.avif 1024w" />
<source type="image/webp" srcset="/hero-480.webp 480w, /hero-1024.webp 1024w" />
<img src="/hero-1024.jpg" width="1024" height="576" alt="Hero" />
</picture>Code-split per route, tree-shake unused exports, audit dependencies for "moment.js-style" bloat. Most sites can shed 30–60% of their JS without losing functionality. Less JS shipped = less JS parsed = better INP.
Inline critical CSS for above-the-fold content; defer the rest. Add defer or async to non-critical script tags. The browser cannot paint until every render-blocking resource has loaded — shrink that set aggressively.
Hero images often start downloading too late because they're discovered deep in the parsed HTML. Preload them with fetchpriority="high" so the browser fetches them before parsing the rest of the document.
<link rel="preload"
as="image"
href="/hero-1024.avif"
type="image/avif"
fetchpriority="high" />Subset fonts to the characters you actually use, self-host instead of relying on third-party domains, and tune fallback metrics so the swap from system font to custom font doesn't reflow the page. font-display: swap with matched size-adjust on the fallback is the modern recipe.
Add loading="lazy" to images below the fold and loading="lazy" to iframes. For more control, use IntersectionObserver to defer expensive third-party widgets until they scroll into view.
Tag managers, analytics, ads, and chat widgets often account for 40–60% of total JavaScript. List every third party loaded on a typical page; for each one, ask "does this need to load on first paint?" Most don't.
Every image, video, ad slot, embed, and skeleton needs explicit dimensions. The cheapest CLS fix is width/height attributes on images; the next is wrapping ads in fixed-size containers so an empty slot is preferable to a layout jump.
Lock in your wins by failing CI when a build regresses past the budget. Typical budgets: LCP < 2.5 s, INP < 200 ms, JS bundle < 200 KB compressed. Without a budget, every team that touches the codebase silently erodes performance.
What's happening: Team spends weeks on image compression and code splitting; LCP barely moves. TTFB is 2 seconds because the origin is uncached and geographically distant — every page inherits that delay.
Fix: Always fix the server tier first. Edge caching plus a CDN typically delivers more LCP improvement in a week than asset work delivers in a month.
What's happening: Team aggressively compresses every image, including small icons. The bytes saved are negligible; the actual LCP element is a render-blocking script that still hasn't been touched.
Fix: Identify the actual LCP element first (Greadme deep scan or Chrome DevTools). Optimize that element. Generic site-wide optimization is the slowest path to a measurable win.
What's happening: Marketing adds a new pixel every quarter. INP slowly drifts from 150 ms to 320 ms over a year. No single change is to blame, but the cumulative cost is severe.
Fix: Audit third parties quarterly. For every new tag, require deferred loading and a removal date if it doesn't produce measurable value.
What's happening: A massive optimization sprint ships, scores recover, then drift 5–10% worse every quarter as new features land. By the next year, the site is back where it started.
Fix: Add a budget enforced in CI. The whole engineering org needs to feel performance regressions at PR time, not in a Search Console alert six months later.
Each layer of the stack moves a different metric. Use this table to match the problem you have to the work you should do.
| Layer | Primary Metric Moved | Effort | Typical Impact |
|---|---|---|---|
| Server tier (cache, CDN, origin) | TTFB → LCP | Medium | Highest — every page benefits |
| Critical render path | FCP, LCP | Medium | High |
| Image / asset optimization | LCP, byte weight | Low–Medium | High |
| JavaScript reduction / splitting | TBT, INP | Medium–High | High |
| Font optimization | FCP, CLS | Low | Medium |
| Stability fixes (sizes, reservations) | CLS | Low | Medium |
| Performance budgets / RUM | All (regression prevention) | Low | Continuous |
Google's Core Web Vitals thresholds, measured at the 75th percentile of real users: LCP ≤ 2.5 s, CLS ≤ 0.1, INP ≤ 200 ms. Supporting metrics: TTFB < 800 ms, FCP < 1.8 s, Total Blocking Time < 200 ms in lab. Hit those at the 75th percentile on mobile and you pass the ranking signal.
Start with the server tier. Edge caching plus a CDN compresses TTFB across every page on the site, and every other metric inherits that improvement. Only after TTFB is consistently under 800 ms should you tackle the critical render path, then assets, then runtime, then stability.
Industry analysis consistently shows roughly 1–2% conversion lift per 100 ms of speed improvement on commerce sites. Compounded across mobile traffic, that is the difference between a profitable channel and an unprofitable one. Google research has also reported sharp bounce-probability climbs on mobile loads over 3 seconds.
Yes — Core Web Vitals (LCP, CLS, INP) are part of Google's Page Experience ranking system, confirmed since the 2021 update. Google uses field data from the Chrome User Experience Report, not synthetic lab scores, for the ranking signal. The 75th-percentile threshold is what determines pass / fail per page group.
Add a performance budget enforced in CI: e.g. fail the build when LCP exceeds 2.5 s on a representative URL or when the JavaScript bundle grows past 200 KB compressed. Pair with real-user monitoring (the web-vitals.js library plus your analytics endpoint) and a monthly crawler scan to catch what budgets miss.
Indirectly but meaningfully. Generative answer engines source most citations from pages already ranking well in traditional search — and Core Web Vitals are part of that ranking signal. Google AI Overviews specifically prefers pages that pass Web Vitals. A faster page wins both traditional ranking and AI citation share at the same time.
Run a deep scan on the most important URL after every release, a crawler scan across the whole site monthly, and a Google Search Console field-data review every 28 days. Performance regressions are slow and incremental — the only way to catch them is with a fixed cadence.
Performance optimization is a stack, not a checklist. Fix the server tier first because every page inherits TTFB. Then shrink the critical render path, then optimize the assets that flow through it, then tame runtime JavaScript, then lock down stability, and finally add monitoring so the wins survive contact with the next quarter's feature work.
The fastest way to see the layers in your own stack is to run a Greadme deep scan. It returns every Core Web Vital, names the specific elements dragging each one down, and pairs every issue with an AI-generated fix or a one-click GitHub PR — so you can spend your time shipping the change instead of finding it.