⚡ Quick answer: What are Core Web Vitals and why does site speed matter for SEO?
Core Web Vitals are three real-world user experience metrics — LCP (loading speed, Good ≤ 2.5s), INP (responsiveness, Good ≤ 200ms), and CLS (visual stability, Good ≤ 0.1) — that Google uses as a direct ranking signal since June 2021. Site speed matters because slow pages lose users before they engage: a Deloitte study found a 0.1-second improvement in mobile load time raises retail conversion rates by 8.4%, and only 48% of mobile websites currently pass all three Core Web Vitals per the HTTP Archive Web Almanac 2025. That gap is your competitive opportunity.
Why You Can Trust This Guide
1. What Are Core Web Vitals?
Core Web Vitals are a subset of Google's broader Web Vitals initiative — a programme designed to provide unified guidance on the signals that matter most for delivering a great user experience on the web. While the broader Web Vitals set includes diagnostics like Time to First Byte (TTFB) and First Contentful Paint (FCP), Core Web Vitals are the three metrics Google uses directly as ranking signals. They are defined and documented at web.dev/vitals.
The three Core Web Vitals are:
- LCP (Largest Contentful Paint) — measures loading performance: how quickly the largest visible element on the screen renders.
- INP (Interaction to Next Paint) — measures responsiveness: how quickly the page reacts to every user interaction throughout the visit.
- CLS (Cumulative Layout Shift) — measures visual stability: how much page content unexpectedly shifts around during and after loading.
These three metrics were selected by the Chrome team because each captures a distinct dimension of user frustration that correlates strongly with abandonment: waiting for content to appear, waiting for actions to register, and watching the page jump around. The selection process and threshold methodology are documented in Google's threshold definition paper on web.dev — a methodology paper explaining how CrUX data from millions of real sessions was analysed to identify the threshold values that best predicted whether a user would stay on a page or abandon it.
| Metric | What it measures | Good ✅ | Needs Improvement ⚠️ | Poor ❌ |
|---|---|---|---|---|
| LCP — Largest Contentful Paint | Loading speed of the main visible content element | ≤ 2.5s | 2.5s – 4.0s | > 4.0s |
| INP — Interaction to Next Paint | Responsiveness to all user inputs throughout the page session | ≤ 200ms | 200ms – 500ms | > 500ms |
| CLS — Cumulative Layout Shift | Visual stability during and after loading | ≤ 0.1 | 0.1 – 0.25 | > 0.25 |
Source: Google Web Vitals documentation, web.dev — thresholds stable as of June 2026, no announced changes.
2. Why Core Web Vitals Matter for SEO
Core Web Vitals became an official Google ranking signal with the Page Experience update in June 2021. Since then, their influence has grown steadily — particularly for competitive SERPs where top-ranking pages have comparable content quality. In those situations, Core Web Vitals function as a tiebreaker: the page with a measurably better user experience wins more often than not. This framing is corroborated by the HTTP Archive Web Almanac 2025 SEO chapter, which documents consistent year-over-year improvement yet confirms more than half the mobile web still fails to pass all three thresholds.
The trend is meaningful: mobile CWV pass rates have risen steadily — 36% in 2023 → 44% in 2024 → 48% in 2025. In highly competitive niches, passing all three metrics is increasingly table stakes. The edge now comes from how comfortably you clear the thresholds, not just whether you do.
The commercial case is equally compelling. Google's Think with Google mobile speed study (SOASTA, millions of sessions) found bounce probability rises 32% when load time goes from 1 second to 3 seconds — and 90% at 5 seconds. Deloitte Digital's Milliseconds Make Millions study quantified a 0.1-second improvement in mobile load time as worth 8.4% more retail conversions. Performance is not an infrastructure concern — it is a revenue variable.
3. How Core Web Vitals Scoring Works
Each metric is scored at the 75th percentile of real user visits — the value that 75% of visits to that URL meet or beat. The score is set by your slowest users, not your typical ones. A fast experience for 80% of visitors does not pass CWV if your slowest 25% still receive a poor one.
To achieve an overall "Good" assessment for a URL, all three metrics must individually reach the Good threshold at the 75th percentile simultaneously. If any single metric fails, the URL's overall status is determined by its worst-performing metric, regardless of how strong the other two are. Google's Core Web Vitals developer documentation confirms URL-level assessment requires all three to pass. Scores reflect rolling 28-day CrUX data per Google's CrUX methodology.
4. Field Data vs. Lab Data: What Actually Counts for Rankings?
Field data (real-user monitoring, or RUM data) is collected from actual Chrome browser sessions visiting your site. It is aggregated into the CrUX dataset and is the only data source that affects Google rankings. Field data reflects the true distribution of experiences across devices, browsers, and network conditions — including slow hardware and congested networks that lab tools cannot replicate.
Lab data is generated by simulating a page load under controlled conditions using tools like Lighthouse, PageSpeed Insights, or WebPageTest. It is reproducible and excellent for diagnosing root causes, but it does not affect rankings. As Google's web.dev lab vs. field documentation explains, lab tools run on a single simulated device — they cannot capture the diversity of your real audience's hardware.
5. Speed Testing Tools: The Complete Toolkit
Use field data tools to understand what Google sees and prioritise fixes. Use lab data tools to diagnose root causes. Neither alone is sufficient.
| Tool | Data Type | Best Used For | Free? |
|---|---|---|---|
| Google Search Console | Field (CrUX) — site-wide | Start every CWV project here. Shows which URL groups are failing and by which metric. The Core Web Vitals report is the most actionable view of your field data. | Yes |
| PageSpeed Insights pagespeed.web.dev | Field + Lab (Lighthouse) | Per-page field data alongside Lighthouse diagnostics on the same screen. Shows CrUX field data for LCP, INP, CLS and a Lighthouse score with specific Opportunities and Diagnostics. | Yes |
| Chrome DevTools Lighthouse | Lab — local | Detailed diagnostics: exact render-blocking files, image savings by file, unused JS by bundle name. Run in Incognito to avoid extension interference. | Yes |
| Web Vitals Chrome Extension | Field — live session | Real-time LCP, INP, CLS readings while browsing your own site. Watch CLS shift events accumulate as you scroll. Essential for diagnosing CLS root elements. | Yes |
| WebPageTest webpagetest.org | Lab — real browsers globally | Waterfall chart analysis; geographic TTFB variance testing; real Moto G Power mobile device testing for the most realistic mobile picture available without owning the device. | Yes (free tier) |
| CrUX Dashboard Looker Studio | Field (CrUX) — historical | Historical CWV trends at origin or URL level over months. Essential for demonstrating improvement after a remediation project — shows the 28-day rolling data in a clear timeline chart. | Yes |
| Screaming Frog + PSI API | Lab — bulk | Bulk PageSpeed Insights analysis across large site crawls — useful for identifying the worst-performing URL groups at scale when Search Console URL groups are not granular enough. | Paid (SF) |
Recommended workflow: Start in Search Console (field data, site-wide). Dig into specific failing URLs in PageSpeed Insights (field + lab per URL). Use Lighthouse for diagnosing the specific render-blocking files, unused JS, or image savings available. Use WebPageTest for waterfall analysis and real mobile device testing. Use the CrUX Dashboard to track improvement over time.
6. How Site Speed Affects SEO — The Five-Layer Stack
Site speed affects SEO on two fronts: directly through Core Web Vitals as a confirmed ranking signal, and indirectly through engagement metrics. A site loading in 1 second converts at roughly 3× the rate of a 5-second site per Portent research across 100 million page views. The speed stack spans five distinct layers — identifying which layer a problem originates in is the prerequisite for selecting the right fix. Treating a TTFB problem with JavaScript minification produces no measurable improvement.
🏗️ Priority 1: Infrastructure
If your server is slow, nothing else matters much. A 600ms TTFB on shared hosting drags LCP into Poor territory regardless of image compression. Fix hosting, caching, and CDN before anything else.
🖼️ Priority 2: Images
Images account for 60–70% of total page weight on the average site. Format conversion to WebP/AVIF produces the largest byte savings per hour of effort and has the most direct impact on LCP.
🚧 Priority 3: Render-Blocking
Nothing frustrates users like a blank screen while the browser waits on a stylesheet or synchronous script. Eliminating render-blocking resources is often the single most visible improvement per Google's render-blocking guide.
📦 Priority 4: JavaScript
Heavy JS blocks the main thread and kills INP — especially on mid-range Android devices where most of your real users are. Every kilobyte must be parsed and executed before interactions become reliable.
💾 Priority 5: Compression & Cache
Compression cuts data on first visits. Caching means returning users skip the download entirely. Together they make repeat visits feel almost instant, especially for loyal audiences.
🔠 Priority 6: Fonts & Third Parties
Impact varies by site. A site loading four Google Fonts families and eight marketing scripts has huge gains here. A site with one self-hosted font and clean scripts? Much less. Audit what you have before deciding depth.
7. Optimisation Priority Framework — Highest Impact First
📊 Relative Impact on PageSpeed Insights Scores — 150+ Client Audits
Based on patterns across 150+ client audits at IndexCraft (2019–2026). Actual gains vary by baseline. Corroborated by HTTP Archive Web Almanac 2025.
8. TTFB: Server Response Time, OPcache, Redis, and Full-Page Caching
Time to First Byte is the elapsed time between a browser sending a request and receiving the first byte of the HTML response. Nothing can happen — no asset requests, no rendering — until that first byte arrives. Google's TTFB guidance on web.dev recommends targeting under 200ms; 800ms is the outer acceptable bound.
OPcache caches compiled PHP bytecode in shared memory, eliminating parse-and-compile overhead on every request. Without it, each request incurs 10–50ms of unnecessary PHP compilation. With OPcache properly configured, this is eliminated — reducing PHP execution time by 30–70% for typical CMS workloads. Key production settings: opcache.memory_consumption=256, opcache.max_accelerated_files=20000, opcache.validate_timestamps=0 (disable disk checks; invalidate manually on deploy). See PHP OPcache documentation.
Object caching stores results of expensive database queries in Redis (in-memory key-value store), serving subsequent requests from RAM rather than re-executing the query. For a typical WordPress site, WP_Query calls for nav menus, widget areas, post metadata, and options number in the dozens per page request. Redis typically reduces TTFB by 40–150ms on database-heavy sites. See Redis documentation.
Full-page caching stores the complete HTML response and serves it directly — bypassing PHP, database queries, and template rendering entirely. For a WordPress site without caching, a page request takes 400–800ms TTFB on a well-provisioned server. The same page from a full-page cache takes 15–60ms. Options: WP Rocket or W3 Total Cache at application layer; Varnish at server layer; Cloudflare APO at edge (~$5/month), reducing TTFB from 300–600ms to 20–60ms per Kinsta's Cloudflare APO benchmark analysis.
9. Hosting Tier Comparison
Hosting sets the floor for everything else. TTFB ranges below are baseline performance with no caching applied, based on WebPageTest benchmarks and published data from Kinsta's WordPress hosting performance benchmarks.
Shared Hosting
TTFB: 400–1,200msCPU, memory, and I/O shared across hundreds of sites. Performance degrades unpredictably under traffic spikes from other tenants. No server configuration control. Adequate only for low-traffic static sites. Migrate to anything else if organic search is a goal.
Managed Cloud
TTFB: 150–400msProviders: Kinsta, WP Engine, Cloudways, SiteGround Cloud. Pre-configured NGINX, PHP-FPM, Redis, and edge caching included. Practical step-up for small-to-medium WordPress sites without server management overhead.
VPS / Self-Managed
TTFB: 80–200msDigitalOcean, Linode, Vultr, AWS EC2. Full control to configure NGINX, PHP-FPM, OPcache, Redis, Brotli, HTTP/2, HTTP/3, and Varnish. Best performance-per-dollar for technically capable teams.
Edge / Serverless
TTFB: 20–80msCloudflare Workers, Vercel Edge, Netlify Edge Functions. Application code executes at the CDN edge node nearest the user, near-eliminating geographic round-trip latency. Best-in-class for JAMstack and Next.js architectures.
10. HTTP/2 and HTTP/3: Protocol Upgrades That Speed Every Request
HTTP/2 addresses HTTP/1.1's concurrency limitation through request multiplexing — sending all requests simultaneously over a single TCP connection. HPACK header compression reduces overhead. Supported by all modern browsers and virtually all major hosts and CDNs. Verify: curl -I --http2 https://yourdomain.com — the response should show HTTP/2. Typically improves load time 15–40% versus HTTP/1.1 for resource-heavy pages. Standardised as RFC 9113.
HTTP/3 replaces TCP with QUIC — a UDP-based transport standardised as RFC 9114. HTTP/2 over TCP suffers head-of-line blocking when a single TCP packet is lost: all multiplexed streams wait for retransmission. QUIC handles packet loss per-stream. Produces the most significant gains on high-latency or lossy connections: mobile networks, cross-continental connections, congested WiFi. Cloudflare reports HTTP/3 reduces connection time by 12–15% on average per their HTTP/3 performance analysis.
11. CDN Configuration: Edge Delivery, Cache Rules, Cache Invalidation
A CDN distributes copies of your assets across edge servers globally, serving each user from the nearest node. Round-trip latency to an origin server might be 180ms for an international request; from the nearest CDN edge it drops under 10ms. Cloudflare's network covers over 320 cities globally as of 2026.
Standard CDN configurations cache static assets: images, CSS, JavaScript, fonts, video, PDFs. Standard configurations do not cache dynamically generated HTML — a CMS page personalised by login state or cart contents requires per-user generation. Advanced CDN products extend caching to dynamic HTML: Cloudflare APO for WordPress caches full HTML at edge nodes with intelligent bypass rules for logged-in users and checkout pages.
Cloudflare free tier provides global edge delivery, DDoS protection, automatic HTTPS, HTTP/2 and HTTP/3, and Brotli compression. For India-focused sites: Cloudflare and Akamai have dense edge networks across Tier-2 Indian cities — Mumbai, Chennai, Delhi, Bangalore, Hyderabad, Kolkata. Always run WebPageTest from Mumbai, Bangalore, and Delhi before and after CDN deployment when your primary audience is Indian — US or European test results are meaningless for your actual users.
Use filename-based cache busting: include a content hash in each asset filename (main.a3f9d2.css not main.css). When the file changes, its filename changes — a new URL the CDN fetches fresh. Modern build tools (webpack, Vite, Parcel) generate content-hashed filenames automatically. For HTML pages, use the CDN's instant cache purge API. See Cloudflare Cache Purge documentation.
12. Gzip vs Brotli: Cutting Transfer Size for All Text Assets
HTTP compression reduces byte size of text-based assets transferred from server to browser. A 200KB JavaScript bundle compressed to 55KB with Brotli saves 145KB per visit — roughly 500ms–1 second of transfer time on a typical mobile connection. Enabling compression is a single server configuration change requiring zero code or content changes.
✅ Brotli (br) — use this first
- 15–26% smaller than Gzip for typical web assets; 60–80% smaller than uncompressed text, per Google's original Brotli publication
- ~97% global browser support in 2026 per Can I Use
- Use level 4–6 for dynamic on-the-fly; pre-compress statics at level 11 during build for maximum savings
↩️ Gzip — always enable as fallback
- 55–75% smaller than uncompressed; universal support across 100% of browsers, CDNs, and proxy servers
- Keep enabled — browser's
Accept-Encodingheader tells the server which algorithms it supports; server returns the best available - Never disable Gzip when adding Brotli — older enterprise firewalls may strip Brotli encoding
# Requires ngx_brotli module (bundled on most managed hosts) brotli on; brotli_comp_level 6; brotli_types text/html text/css application/javascript application/json image/svg+xml font/woff2; gzip on; gzip_comp_level 6; gzip_types text/html text/css application/javascript application/json image/svg+xml; gzip_vary on; # Adds Vary: Accept-Encoding — required for correct CDN caching
13. Eliminating Render-Blocking Resources
Render-blocking resources force the browser to pause page construction until fully downloaded and processed — showing the user a blank screen. A page with three render-blocking scripts and two render-blocking stylesheets each taking 200ms to download shows a blank screen for over a second regardless of TTFB. Per Google's render-blocking resources guide, this is one of the highest-impact improvements on most real-world sites.
<!-- Inline critical CSS, async-load full stylesheet --> <style>body{font-family:sans-serif;margin:0}.hero{padding:60px 0;background:#1e1b4b;color:#fff}</style> <link rel="preload" href="/styles/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="/styles/main.css"></noscript> <!-- ❌ Render-blocking — blocks HTML parsing --> <script src="/js/app.js"></script> <!-- ✅ Deferred — downloads in background, executes after HTML is parsed --> <script src="/js/app.js" defer></script> <!-- ✅ Async — for independent third-party scripts with no dependencies --> <script src="https://3rdparty.com/widget.js" async></script>
14. Critical CSS: Inlining Above-the-Fold Styles for Instant First Paint
Critical CSS is the subset of CSS rules required to render the content visible without scrolling. Inlining it in the HTML <head> allows the browser to begin rendering immediately upon receiving the HTML response — without waiting for any external stylesheet. Documented in Google's Extract Critical CSS guide.
Method 1 — Automated npm tooling: The critical npm package extracts above-the-fold CSS automatically: npx critical src/index.html --inline --width 1300 --height 900 --dest dist/index.html.
Method 2 — Chrome DevTools Coverage tab: Open DevTools → More Tools → Coverage → reload. CSS lines highlighted in red are unused on initial load; green lines are critical CSS candidates. Useful for understanding which rules are truly above-the-fold before automating.
Method 3 — Lighthouse Opportunities: The "Eliminate render-blocking resources" opportunity identifies which stylesheets are blocking and how much time each adds — use this to prioritise files before investing in full extraction.
15. LCP: Largest Contentful Paint — Deep Dive and 7 Proven Improvements
🟢 LCP — Largest Contentful Paint
Good: ≤ 2.5s | Needs Improvement: 2.5s–4.0s | Poor: > 4.0s
Source: web.dev/lcp
LCP measures the time from page load start to when the largest content element in the viewport has fully rendered. Google chose LCP because it closely matches when users perceive a page as loaded — earlier metrics like First Contentful Paint could be satisfied by a tiny spinner or loading indicator. Per the HTTP Archive Web Almanac 2025, only 62% of mobile pages achieve a good LCP score — versus 77% for INP and 81% for CLS — making LCP the metric pulling the overall mobile pass rate down to 48%. Fix it first.
LCP breaks into four diagnosable sub-components (per web.dev/optimize-lcp):
- TTFB: How quickly the server responds. Target under 200ms.
- Resource load delay: Time between first HTML byte and browser discovering the LCP resource. Minimised by preload hints early in
<head>. - Resource load duration: Download time. Reduced by image compression and CDN edge delivery.
- Element render delay: Time between resource finish and element painting. Often caused by render-blocking JavaScript or CSS.
How to improve LCP
fetchpriority="high"Add a <link rel="preload"> in <head> for the hero image. This tells the browser to fetch the LCP resource as early as possible — before it would normally be discovered during HTML parsing. This single change can reduce LCP by 0.5–1.0 seconds. In a documented Google test on Google Flights, adding fetchpriority="high" alone improved LCP from 2.6s to 1.9s per Google's preloading guide.<link rel="preload" as="image" href="hero.webp" fetchpriority="high">
WebP images are typically 25–35% smaller than equivalent JPEGs. AVIF goes further — up to 50% smaller — per Google's AVIF compression research. Always use the <picture> element to serve AVIF with a WebP or JPEG fallback.
TTFB is the foundation of LCP — if the server is slow, every downstream metric suffers. Use a CDN to cache HTML responses at edge locations, enable server-side caching (Redis, Varnish, or full-page cache), and use the Server-Timing header to diagnose exactly where server time is spent. Target under 200ms per web.dev TTFB guidance.
Per the 2025 Web Almanac, 7% of websites still load their LCP image via JavaScript or a data-src attribute — hiding it from the browser's preload scanner entirely. The browser cannot start downloading the LCP image until JS executes, typically several hundred milliseconds after HTML is received. The LCP image URL must appear in the raw HTML source for the preload scanner to find it.
loading="lazy" to the LCP imageThis is one of the costliest single-line mistakes — a loading="lazy" attribute on the hero image. Lazy loading defers the fetch until the element is near the viewport, but the LCP image is the viewport. It can add 1–2 seconds to LCP alone. The 2025 Web Almanac confirms 7% of websites still make this specific mistake. Set loading="eager" (the default) or add fetchpriority="high" explicitly.
A CDN distributes assets across globally distributed edge servers so users receive content from the nearest node. For sites with significant traffic from India or South-East Asia, prioritise providers with strong regional PoP coverage — Cloudflare and Akamai have particularly dense networks across Tier-2 Indian cities.
On pages where the LCP element is a large heading or introductory paragraph (not an image), font loading directly delays LCP. If the web font is not yet available when the browser tries to paint, the element remains invisible. Use font-display: optional or font-display: swap to ensure text renders immediately. Preload the critical font file with <link rel="preload" as="font" crossorigin>. Self-hosting fonts rather than loading from Google Fonts eliminates an additional cross-origin DNS lookup and connection overhead.
loading="lazy" from their theme. Real users on mobile were waiting 5.2 seconds for it. Converting to WebP with responsive sizing, removing the lazy attribute, and adding a preload hint brought field LCP to 2.1 seconds within five weeks. No template changes, no hosting changes. — Rohit Sharma
16. INP: Interaction to Next Paint — Deep Dive and 5 Proven Improvements
🔵 INP — Interaction to Next Paint
Good: ≤ 200ms | Needs Improvement: 200ms–500ms | Poor: > 500ms
Source: web.dev/inp
INP replaced First Input Delay (FID) as a Core Web Vital in March 2024 per Google's Chrome developer blog. FID only measured delay before the browser began processing the first interaction. INP measures the complete latency of all clicks, taps, and keyboard inputs throughout the entire page lifecycle — a far stricter and more honest measure of whether a page feels responsive. The INP score is the worst interaction latency across the visit (statistical outliers removed). Per the 2025 Web Almanac, 77% of mobile pages achieve a good INP score — the strongest-performing of the three mobile metrics.
High INP almost always traces back to long JavaScript tasks on the main thread. The three phases of an INP interaction are:
- Input delay: Time the browser waits before starting to process the interaction — other tasks are blocking the main thread.
- Processing time: Time spent executing event handlers and rendering logic.
- Presentation delay: Time between the browser finishing processing and painting the next frame.
How to improve INP
Third-party scripts — analytics tags, advertising pixels, chat widgets, A/B testing tools — are the single most common source of INP failures. Open Chrome DevTools → Performance → record a page interaction → look at the Bottom-Up tab sorted by Total Time. Identify which scripts consume main-thread time, then remove or defer any not essential to a measurable business outcome.
scheduler.yield()For unavoidable long JavaScript tasks, use the Scheduler API to yield control back to the browser between work chunks. This allows the browser to process pending user interactions before resuming. See web.dev Optimize Long Tasks guide:
async function processData(items) {
for (const item of items) {
processItem(item);
await scheduler.yield(); // Yield to browser between each item
}
}
Note: scheduler.yield() is available in Chrome 115+. For broader compatibility, use setTimeout(resolve, 0) wrapped in a Promise as a fallback.
Heavy event handlers that mix synchronous DOM reads (offsetHeight, getBoundingClientRect()) with DOM writes force the browser to recalculate layout mid-task — called forced synchronous layout. This can multiply interaction processing time by 5–10×. Always batch DOM reads before DOM writes, or use a library like FastDOM that enforces this separation.
Do not ship the entire application bundle on initial page load. Use dynamic import() to split code into chunks that load only when a feature is needed. A well-implemented code-splitting strategy can reduce initial JavaScript that must parse and compile during startup by 40–60%, reducing long tasks that block early interactions.
defer and async correctly for all scriptsAny JavaScript not needed during the critical rendering path must be deferred. Add defer to scripts with dependencies that must execute in order after HTML parsing. Use async for independent scripts with no dependencies. Never place synchronous scripts without defer or async before your main content in <head> — these block both HTML parsing and rendering, extending input delay across the entire early page lifecycle.
17. CLS: Cumulative Layout Shift — Deep Dive and 5 Proven Improvements
🟠 CLS — Cumulative Layout Shift
Good: ≤ 0.1 | Needs Improvement: 0.1–0.25 | Poor: > 0.25
Source: web.dev/cls
CLS measures the visual instability of a page. The score is calculated from individual layout shift events, each scored by multiplying the fraction of the viewport the shifted element occupied by the distance it moved as a fraction of the viewport height. CLS accumulates shifts throughout the page visit using a windowing algorithm (introduced in 2021) that groups shifts occurring within 1 second of each other into sessions, capping each session at 5 seconds. Per the 2025 Web Almanac, 81% of mobile pages achieve a Good CLS score — making it the best-performing metric. Still, 1 in 5 mobile pages fails, and CLS failures cause accidental clicks and taps that directly harm conversions.
How to improve CLS
When the browser knows an image's dimensions before it loads, it reserves the correct space — no shift when the image appears. <img width="800" height="450" src="...">. In CSS, use the modern aspect-ratio property as an alternative when dimensions vary. Per Google's CLS documentation, missing dimensions are among the most widespread causes of CLS across the web.
Cookie banners, notification bars, promotional popups, and ad units inserted above existing content after initial render cause layout shifts. Pre-allocate space with a fixed-height placeholder, or display overlays using position: fixed so they sit outside the document flow and do not displace content.
Animations changing top, left, margin, or padding trigger layout recalculations and contribute to CLS. Use transform: translate() and opacity instead — these are GPU-composited and do not affect page layout. Documented in Google's animations performance guide.
font-display: optional or preloadingWhen a web font loads and swaps in after the fallback font, different character widths cause text reflow and layout shifts. font-display: optional uses the fallback font if the web font isn't available within a short timeout — eliminating FOUT-induced CLS. For brand fonts where exact rendering matters, font-display: swap combined with font preloading is a reasonable compromise.
When PageSpeed Insights is not specific enough about the CLS source, run this snippet in your browser console:
new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (!entry.hadRecentInput) {
console.log('CLS shift:', entry.value, entry.sources);
}
});
}).observe({type: 'layout-shift', buffered: true});
The entry.sources array identifies the exact DOM elements involved — the fastest way to find the root element.
18. JavaScript Optimisation: Bundle Splitting, Tree Shaking, and Minification
JavaScript is the heaviest performance challenge in modern web development — every kilobyte must be parsed, compiled, and executed, blocking the main thread. Per the HTTP Archive Web Almanac 2025 JavaScript chapter, the median mobile page loads 570KB of JavaScript (uncompressed). A 500KB bundle on a mid-range Android device can block the main thread for 2–4 seconds, directly causing Poor INP.
Without splitting, a page using 10% of your application's total JavaScript still downloads and parses the entire bundle. Dynamic import() (supported by webpack, Vite, Rollup) splits route-specific components into separate chunks that load only when that route is visited. Commonly reduces initial bundle size by 40–60% per Vite's code splitting documentation.
Tree shaking statically analyses imports and removes exported code not used anywhere in your application. Requires ES module syntax (import/export, not CommonJS require()) and is performed automatically by webpack (production mode), Vite, Rollup, and esbuild. Verify with webpack-bundle-analyzer or vite-bundle-visualizer.
Modern minifiers (Terser, esbuild, SWC) remove whitespace, comments, and long variable names, plus perform constant-expression evaluation and dead code elimination. Minification typically reduces JavaScript size by 20–40% before compression — combined with Brotli, production JS is commonly 70–85% smaller than development source. Un-minified JavaScript in production is never appropriate.
Any JavaScript task running over 50ms is a "long task" — it blocks the main thread for its entire duration, directly causing Poor INP. Diagnose with Chrome DevTools Performance panel: record a page load and examine the Main thread row for red-capped tasks over 50ms. Common sources: large synchronous execution on page load, heavy third-party scripts, non-virtualised long lists rendering thousands of DOM nodes. Fixes: use scheduler.yield(); move heavy computation to Web Workers. See web.dev Optimize Long Tasks.
19. CSS Optimisation: Minification and Unused CSS Removal
CSS minification removes all whitespace, comments, and redundant syntax without changing behaviour. A typical stylesheet minifies to 60–75% of its original size. PostCSS with cssnano, Vite, and webpack's css-minimizer-webpack-plugin all perform this automatically in production mode. This is a zero-effort, zero-risk optimisation that should be part of every build pipeline.
CSS frameworks like Bootstrap ship complete component libraries. A site using 20% of Bootstrap ships a 140KB minified stylesheet without PurgeCSS and a 12–20KB stylesheet after — an 85–90% size reduction. PurgeCSS analyses your HTML, JavaScript, and templates to determine which CSS selectors are actually used. For Tailwind CSS, the built-in content configuration in tailwind.config.js performs the same tree-shaking automatically on every production build. See PurgeCSS documentation.
20. Image Optimisation: Format, Compression, srcset, Lazy Loading, Image CDN
Images represent 60–70% of total page weight on the average website per the HTTP Archive 2025 Page Weight chapter. Format selection, compression, responsive delivery, and loading strategy together can reduce image payload by 70–85% with no visible quality reduction — consistently the highest-ROI optimisation layer for content-heavy sites.
Relative file size for a typical 800×600 photograph at equivalent visual quality (JPEG = 100% baseline). Sources: Google AVIF research and Google WebP study.
<!-- Above-fold LCP hero — eager load + high priority --> <picture> <source type="image/avif" srcset="hero.avif 1x, hero-2x.avif 2x"> <source type="image/webp" srcset="hero.webp 1x, hero-2x.webp 2x"> <img src="hero.jpg" srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w" sizes="(max-width:600px) 400px, (max-width:1024px) 800px, 1200px" width="1200" height="630" alt="Descriptive alt text for this hero image" loading="eager" fetchpriority="high"> </picture> <!-- Below-fold images — lazy load to defer network requests --> <img src="article-image.webp" width="800" height="450" alt="..." loading="lazy">
Image CDN services (Cloudinary, Imgix, Bunny.net Optimizer, Cloudflare Images) perform format conversion, compression, and responsive resizing automatically on request. You upload originals; the image CDN serves each request with the optimal format for the browser, correct dimensions for the device, and best compression level. For quick one-off conversions, use IndexCraft's free Image Converter tool or the browser-based Squoosh by Google.
21. Font Loading Optimisation: font-display, Preconnect, Subsetting, Self-Hosting
Web fonts cause invisible text during load (FOIT) and — for third-party font CDNs — an additional cross-origin connection overhead. Per the HTTP Archive Web Almanac 2025 Fonts chapter, 80% of mobile pages use web fonts, making font loading optimisation one of the most widely applicable improvements available.
font-display: swap instructs the browser to render text using a system font fallback while the web font downloads, then swap it in when it arrives. This prevents FOIT. For Google Fonts, append &display=swap to the font URL. Full spec at MDN font-display documentation.
rel="preconnect" establishes TCP connection, TLS handshake, and DNS lookup for a third-party domain before any request from it has been made. For Google Fonts, add these two tags in <head> before the Fonts link tag:<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
This eliminates 100–300ms of connection setup overhead per Google's font best practices guide.
Hosting fonts on your own domain eliminates cross-origin connection overhead entirely and gives you full control over Cache-Control headers. Download WOFF2 files from google-webfonts-helper, place them in your static assets directory, and reference via @font-face declarations. WOFF2 is the correct default — universally supported and typically 30% smaller than WOFF.
A full Unicode web font covers thousands of characters. An English-language site needs only Basic Latin. The Latin subset of a typical web font is 20–40KB versus 150–300KB for the full Unicode version — a 75–85% size reduction. Use pyftsubset (part of fonttools) to generate custom WOFF2 subsets containing only the Unicode ranges present in your content.
22. Browser Caching: Cache-Control Headers, ETags, and Cache Busting
✅ Correct caching configuration
- Versioned static assets:
Cache-Control: public, max-age=31536000, immutable— 1 year;immutabletells browsers this file will never change at this URL - HTML pages:
Cache-Control: no-cache— browser must revalidate before using cached copy - Filename content hashing for all versioned assets
Vary: Accept-Encodingon all compressed responses- ETag enabled on HTML — produces 304 Not Modified for unchanged content
❌ Common caching mistakes
- No Cache-Control headers — browser uses heuristic caching (typically minutes)
- Short max-age on static assets — returning users re-download every hour
- Long max-age on HTML — users receive stale page content after updates
- Updating CSS/JS files without changing filename — cached files serve old code
- Missing
Vary: Accept-Encoding— CDN serves uncompressed content to browsers requesting compressed
23. Resource Hints: Preload, Prefetch, Preconnect, dns-prefetch
| Hint | What it does | When to use | When NOT to use |
|---|---|---|---|
| preload | Fetches the resource immediately at high priority before the HTML parser discovers it | Critical above-fold resources discovered late: LCP hero image in CSS, primary web font, critical script loaded via JS. Requires as= attribute. | Don't preload every image — only the LCP element. Unused preloads waste bandwidth and trigger console warnings. |
| prefetch | Fetches a resource at low priority for use on a future navigation | Resources needed on the most common next page — the JS bundle for a frequently visited next route, or a hero image behind a prominent CTA | Do not use for resources needed on the current page — use preload instead. |
| preconnect | Performs DNS lookup, TCP handshake, and TLS negotiation for the origin in advance | Third-party origins from which resources are requested early: font CDN, analytics CDN, image CDN. Reduces setup overhead by 100–300ms per origin. | Limit to 2–3 most critical origins. Opening many connections simultaneously consumes socket pool slots. |
| dns-prefetch | Performs only DNS resolution — lighter-weight than preconnect | Third-party origins from which resources will be requested later or on interaction. Use alongside preconnect for broader browser support. | Do not substitute for preconnect on origins you request in the first 500ms of page load. |
24. Third-Party Script Management: Audit, Async Loading, Facade Patterns
Third-party scripts are one of the most common sources of poor performance on otherwise well-optimised sites. Per the HTTP Archive Web Almanac 2025 Third Parties chapter, the median mobile page makes requests to 17 third-party origins — each adding DNS lookup, connection, and download overhead entirely outside your control.
For each script: Is it actively used? Does it contribute to a measurable business outcome? Common removal candidates: abandoned analytics tags, social sharing buttons with near-zero click rates, marketing pixel duplicates, outdated chat widgets. Every removed script is an unconditional performance improvement — no configuration makes it as fast as not loading it.
Every third-party script tag must have either async or defer. Never include third-party scripts synchronously in the document <head> — this is the most egregious performance anti-pattern and the most common cause of TBT over 500ms. Use async for independent scripts (analytics, advertising). Use defer for scripts that interact with the DOM.
For chat widgets, social comment systems, video embeds: delay loading entirely until the first user interaction. Listen for a scroll, click, or mousemove event to trigger script injection via a once-fired event listener. This removes these scripts from the critical loading path entirely. See Google's efficient third-party loading guide.
Replace a heavyweight embed (YouTube player, Google Maps, Intercom widget) with a lightweight static placeholder — a screenshot or thumbnail image. The real embed loads only when the user clicks. YouTube embeds can add 400–600KB of JavaScript per page; replacing with a facade reduces associated load from 1–2 seconds to under 50ms. See Chrome's Third-party facades guide.
25. Service Workers: Offline Caching and Repeat-Visit Performance
A service worker is a JavaScript file that runs in the background and intercepts network requests. For returning visitors, frequently-used assets can be served from a local cache almost instantly — even on a poor mobile connection. Service workers require HTTPS and same-origin hosting per the MDN Service Worker API documentation.
A cache-first strategy serves assets from the local cache if available and falls back to the network only for uncached assets. For static assets that change rarely (CSS, fonts, icons, library JavaScript), this produces near-instant delivery from local filesystem. The Workbox library by Google simplifies implementation — it provides pre-built strategies (cache-first, stale-while-revalidate, network-first) and handles cache versioning, precaching, and size management automatically. For most sites, cache-first for static assets and stale-while-revalidate for HTML provides the best balance of performance and freshness.
26. Database and Query Optimisation for CMS Sites
Install Query Monitor on staging to see every database query per page request — count, execution time, calling function, and duplicate queries. A healthy WordPress page runs under 50 database queries per request. Pages running 200+ have significant optimisation opportunity. Common sources: unbounded WP_Query with no post limit, plugins querying inside loops without caching, get_option() calls triggering individual queries per option.
Ensure tables use InnoDB (not MyISAM) and key lookup columns are indexed. The most impactful indexing improvement for most WordPress sites: add an index on wp_postmeta.meta_key if post meta queries are flagged slow. Run OPTIMIZE TABLE wp_postmeta, wp_options, wp_posts monthly after large content updates. Configure innodb_buffer_pool_size to 50–70% of available RAM on dedicated database servers. See MySQL InnoDB Buffer Pool documentation.
27. WordPress Speed Optimisation: The Complete Plugin and Configuration Stack
WordPress powers approximately 43.4% of all websites globally as of 2026, per W3Techs CMS market share data. However, the HTTP Archive Web Almanac 2025 CMS chapter shows WordPress has a mobile CWV pass rate of just 45% — among the lowest of major platforms, behind Duda (85%), TYPO3 (79%), Wix (74%), Squarespace, and Joomla. WordPress improved only 4% year-over-year in 2025, compared to Wix's 14% jump — reflecting how difficult it is to propagate improvements evenly across a highly customisable ecosystem.
WP Rocket
Full-stack caching + deliveryThe most comprehensive single WordPress performance plugin — handles full-page caching, Brotli/Gzip, render-blocking JS/CSS deferral, critical CSS, lazy loading, database optimisation, and CDN integration in one interface. Premium (~$59/year). Replaces most other performance plugins.
LiteSpeed Cache
Free full-stack for LiteSpeed hostsThe most powerful free WordPress caching plugin — full-page cache, object cache, CSS/JS minification and deferral, image optimisation, and CDN integration all included. Free at wordpress.org/plugins/litespeed-cache. Excellent alternative to WP Rocket for sites on LiteSpeed hosting.
Cloudflare + APO
CDN + edge HTML cachingFree tier for global CDN, DDoS protection, HTTP/2, HTTP/3, and Brotli. APO (~$5/month) caches HTML at Cloudflare's edge, reducing TTFB from 300–600ms to 20–60ms for cached pages. Most impactful single purchase for WordPress speed on any hosting tier.
Imagify / ShortPixel
Image optimisationBulk-converts the WordPress media library to WebP/AVIF, compresses at configurable quality, and serves the optimised format automatically. Essential for any site with an un-optimised image library inherited from before WebP was standard practice.
Perfmatters
Script & feature managerLightweight script manager for disabling unnecessary WordPress scripts (emojis, embeds, jQuery Migrate, REST API) on a per-page or per-post-type basis. Particularly effective for INP because WordPress core and plugins often enqueue scripts globally even when only needed on specific pages. Premium at perfmatters.io.
Asset CleanUp Pro
Per-page asset controlDisables specific CSS and JavaScript files on a per-page-type basis — removing Contact Form 7 scripts from non-contact pages, WooCommerce cart scripts from non-shop pages. Addresses the plugin bloat problem where plugins load assets globally on every page regardless of relevance.
Redis Object Cache
Database query cachingConnects WordPress to a Redis server for persistent object cache. Caches WP_Query, get_option(), and get_post_meta() results in Redis RAM. Typical TTFB reduction: 40–150ms on query-heavy sites. Free at wordpress.org/plugins/redis-cache.
GeneratePress / Kadence
Lightweight theme recommendationLightweight themes with clean, minimal code that score well on Core Web Vitals out of the box. A significant advantage if you are starting a new build. Avoid heavy page builders like Elementor or Divi if performance is a priority — Elementor accounts for ~43% of WordPress page builder usage and consistently correlates with heavier asset loads per the 2025 Web Almanac.
28. How Core Web Vitals Interact with Other Ranking Factors
Core Web Vitals are one of hundreds of signals in Google's ranking algorithm. Google's own Page Experience documentation is explicit: page experience does not override content quality. Relevance and E-E-A-T come first, then links, then technical signals like CWV.
Good Core Web Vitals will not rescue thin content or compensate for weak links. But poor scores can hold back a page that would otherwise rank well — especially as more sites in a niche improve and the gap between best and worst performers narrows. This is the tiebreaker framing: in competitive SERPs where two pages have comparable content quality, authority, and relevance, the one with measurably better user experience wins more often.
Ahrefs' CWV analysis across millions of URLs found that pages in positions 1–3 had consistently higher CWV pass rates than those in positions 6–10, even when controlling for domain authority. The correlation is modest but consistent across niches. The implication is not that CWV is a dominant ranking factor — it is that failing CWV is a drag on pages that would otherwise perform.
29. Core Web Vitals for E-Commerce
Product pages are the hardest pages to get right on Core Web Vitals. Multiple high-res images, complex JavaScript for variant selectors and cart logic, and tracking and retargeting scripts all hit simultaneously. The HTTP Archive Web Almanac 2025 e-commerce chapter confirms LCP remains the biggest differentiator across e-commerce platforms. The Yottaa 2025 Web Performance Index found one second saved can increase mobile conversions by 3% on average, and poor speed optimisation can result in up to a 22% drop in conversions.
- Lazy-load below-the-fold product images but never the primary product image (your LCP element). Use
loading="lazy"only on images more than one scroll below the fold. - Implement a product image CDN — Cloudinary or Imgix detect browser capability and serve AVIF, WebP, or JPEG automatically at the exact display dimensions needed.
- Audit your tag manager for unused pixels — marketing and retargeting scripts via Google Tag Manager are the leading INP source on product and category pages.
- Reserve space for asynchronously loaded content — reviews, UGC ratings, and recommendation widgets loaded via API are among the most common CLS sources on product pages.
- Test your checkout funnel separately — payment forms, address validators, and cart scripts make checkout pages some of the most JavaScript-heavy on any site, with the worst CWV scores. Prioritise INP fixes specifically for checkout.
30. Mobile vs. Desktop: Why Mobile Scores Are What Matter Most
Google measures Core Web Vitals separately for mobile and desktop. The same three metrics and thresholds apply to both, but mobile scores are consistently harder to achieve — 48% of mobile websites pass all three Core Web Vitals versus 56% on desktop per the 2025 Web Almanac, driven by slower CPUs, less RAM, and variable network quality on mobile devices.
Since Google uses mobile-first indexing (universal since July 2019), your mobile scores are the ones that matter most for rankings. A page scoring Good on desktop but Poor on mobile is still penalised. Prioritise mobile performance analysis and test on mid-range Android devices — not on a high-end iPhone or a development laptop. Chrome DevTools Device Mode with Slow 4G throttling and WebPageTest's real Moto G Power mobile device testing provide the most realistic simulation of real mobile conditions.
31. Rankings, Conversions, and the Business Case for Speed
Core Web Vitals are one of hundreds of signals in Google's ranking algorithm — content quality and E-E-A-T come first. But poor scores can hold back pages that would otherwise rank well, as covered in Section 28. The commercial case is equally strong.
Google's Think with Google mobile speed study (SOASTA, millions of sessions) found bounce probability rises 32% when load time goes from 1 second to 3 seconds — and 90% at 5 seconds. Google and Ipsos research found that for every second of delay in mobile page load, conversions can fall by up to 20%. CLS failures are particularly damaging because they cause accidental clicks and taps — a user intending to hit "Add to Cart" hitting a different element because the layout shifted at the moment of interaction.
32. Performance Budgets: Setting and Enforcing Load Time Targets
A performance budget is a set of limits your team agrees not to cross. The point is having automated tooling that catches regressions before they ship. Documented in Google's Performance Budgets 101 guide.
| Metric | Target (Good) | Acceptable | Action if breached |
|---|---|---|---|
| Total page weight (mobile) | < 500KB | < 1MB | Audit new images and assets added since last passing build |
| JavaScript (compressed) | < 150KB | < 300KB | Run bundle analyser; implement code splitting for new routes |
| CSS (compressed) | < 50KB | < 100KB | Run PurgeCSS; check for newly imported unused framework CSS |
| Third-party requests | < 5 | < 10 | Audit newly added scripts; identify any that can be removed or consolidated |
| TTFB | < 200ms | < 500ms | Check server-side cache hit rate; inspect new database queries from recent code changes |
| PageSpeed Insights mobile score | > 80 | > 65 | Run Lighthouse; address the top Opportunity before deployment |
Integrate Lighthouse CI (lhci npm package) into your GitHub Actions or GitLab CI pipeline. On every pull request, Lighthouse CI audits the built site, compares against your configured thresholds, and fails the build if any threshold is exceeded. Configure in .lighthouserc.json: "assertions": {"categories:performance": ["error", {"minScore": 0.80}]}. This transforms performance budgets from aspirational guidelines into mandatory deployment gates.
33. How Long Before Core Web Vitals Improvements Show in Rankings?
Google updates the CrUX dataset on a rolling 28-day window. Anything deployed today will not fully show up in Search Console for approximately four weeks — old sessions gradually phase out as new ones roll in. This timeline is confirmed in Google's CrUX methodology documentation. There is no way to accelerate this; you cannot request a CrUX cache refresh.
Once field data improves, rankings typically follow within one to two crawl cycles. For frequently-crawled, authoritative pages that can be as quick as 1–2 weeks after CrUX catches up. For less-crawled pages, budget 6–10 weeks from implementation. Allow a full 90 days before making a definitive assessment of ranking impact.
34. Combined Site Speed & Core Web Vitals Audit Checklist
Part A: Core Web Vitals Specific Checklist
| Check | Metric | Tool to Verify |
|---|---|---|
Hero image preloaded with fetchpriority="high" | LCP | PageSpeed Insights |
| LCP image served in WebP or AVIF format | LCP | Chrome DevTools Network tab |
| LCP image URL discoverable in HTML source (not behind JS or data-src) | LCP | Source code review |
| TTFB under 800ms for key URLs (target <200ms) | LCP | WebPageTest / PageSpeed Insights |
| Render-blocking CSS/JS eliminated above the fold | LCP | Lighthouse |
No loading="lazy" on the LCP image | LCP | Source code review |
| CDN in use with regional edge coverage | LCP | WebPageTest waterfall |
| No long tasks (>50ms) during key interactions | INP | Chrome DevTools Performance panel |
| Third-party scripts audited; unnecessary ones removed or deferred | INP | Chrome DevTools Coverage tab |
| JavaScript code-split and lazy-loaded where possible | INP | Lighthouse / Bundle Analyser |
All <img> and <iframe> have explicit width/height attributes | CLS | Source code review / Lighthouse |
| No dynamic content injected above existing page content post-load | CLS | Web Vitals Extension / DevTools Rendering |
| Cookie/consent banners use fixed positioning (not document flow) | CLS | Manual inspection + Web Vitals Extension |
Animations use transform and opacity only | CLS | Chrome DevTools Rendering panel |
Fonts use font-display: swap or optional | CLS | PageSpeed Insights |
| Mobile field data checked in Google Search Console CWV report | All | Google Search Console |
| 75th percentile thresholds met for all three metrics (field data) | All | PageSpeed Insights — Field Data tab |
Part B: Full Site Speed Optimisation Checklist
🏗️ Infrastructure & Protocol
- Hosting tier is managed cloud or VPS — shared hosting migrated away from
- PHP OPcache enabled:
memory_consumption ≥128MB,validate_timestamps=0in production - Redis or Memcached object caching active
- Full-page caching configured (WP Rocket, Varnish, or Cloudflare APO)
- HTTP/2 confirmed via
curl -I --http2 https://yourdomain.com - HTTP/3 enabled if server stack supports it (NGINX QUIC, LiteSpeed, or Cloudflare)
- CDN deployed for all static assets
📦 Compression & Caching
- Brotli enabled for all text MIME types; Gzip enabled as fallback
- Response headers show
Content-Encoding: bron CSS/JS files - Static assets:
Cache-Control: public, max-age=31536000, immutable - HTML pages:
Cache-Control: no-cachewith ETag enabled - Filename content hashing for all versioned static assets in build pipeline
Vary: Accept-Encodingpresent on all compressed responses
🖼️ Images
- All photographs converted to WebP; AVIF served via
<picture>element with fallback - All logos, icons, and line art served as SVG
- All below-fold images have
loading="lazy" - Explicit
widthandheighton every image to prevent CLS - Responsive
srcsetandsizesattributes on variable-width images - Hero/LCP image does NOT have
loading="lazy"applied
🚧 Render-Blocking & JavaScript
- Critical CSS inlined in HTML head; full stylesheet loaded asynchronously
- All first-party JavaScript tags have
defer - All third-party JavaScript tags have
asyncordefer - JavaScript bundle split into route-specific chunks; no initial bundle over 150KB compressed
- Tree shaking confirmed active in production build
- No long tasks over 200ms during typical page load in DevTools Performance panel
- Never load a third-party script synchronously in
<head>— the single most common cause of TBT over 500ms
🔠 Fonts & Third Parties
font-display: swapapplied to all@font-facedeclarationspreconnecthints in HTML head for all font CDN origins- Font subset confirmed: Latin-only or appropriate minimal range for site language
- Third-party script audit complete: every retained script justified
- Heavy embeds (YouTube, Google Maps, chat widgets) use facade pattern
- Non-critical scripts delayed until user interaction event
📊 Measurement & Monitoring
- Mobile field data reviewed in Google Search Console Core Web Vitals report
- 75th percentile thresholds met for all three metrics in field data
- Performance budget set and enforced in CI/CD via Lighthouse CI
- CrUX Dashboard (Looker Studio) configured for historical trend tracking
- 28-day CrUX data lag communicated to stakeholders before remediation project begins
35. Frequently Asked Questions
What are Core Web Vitals?
Core Web Vitals are three real-world user experience metrics defined by Google as part of the Web Vitals initiative: LCP (Largest Contentful Paint) for loading speed, INP (Interaction to Next Paint) for responsiveness, and CLS (Cumulative Layout Shift) for visual stability. They have been a direct Google ranking signal since June 2021. Good thresholds are: LCP ≤ 2.5s, INP ≤ 200ms, CLS ≤ 0.1 — each measured at the 75th percentile of real Chrome user visits.
Do Core Web Vitals affect Google search rankings?
Yes. Core Web Vitals became an official Google ranking signal with the Page Experience update in June 2021, confirmed in Google's Page Experience documentation. Their influence is strongest in competitive SERPs where top-ranking pages have comparable content quality — there, CWV function as a tiebreaker. Poor scores can hold back a page that would otherwise rank well. Good scores alone cannot rescue thin content or compensate for weak links — E-E-A-T and relevance come first.
What is the difference between field data and lab data?
Field data is collected from actual Chrome browser sessions and is the only data that affects Google rankings. It is aggregated in the CrUX dataset and reflects real device diversity, network conditions, and geographic distribution. Lab data (Lighthouse, WebPageTest) is generated under controlled simulated conditions — excellent for diagnosing root causes but not used for rankings. If your Lighthouse score looks fine but Search Console shows Poor, trust the field data — it is measuring your real users. See Google's lab vs. field documentation.
What are the Core Web Vitals thresholds for 2026?
The 2026 thresholds are unchanged from 2024: LCP Good ≤ 2.5 seconds, Needs Improvement 2.5–4.0s, Poor > 4.0s; INP Good ≤ 200ms, Needs Improvement 200–500ms, Poor > 500ms; CLS Good ≤ 0.1, Needs Improvement 0.1–0.25, Poor > 0.25. Source: web.dev/vitals. All three must pass at the 75th percentile of real user visits for a URL to receive an overall Good assessment.
What is TTFB and what is a good target?
TTFB (Time to First Byte) is the time between the browser requesting a page and receiving the first byte of the server's HTML response. Google recommends under 200ms as the ideal target; 800ms is the outer acceptable bound. The three levers: better hosting infrastructure, server-side caching (OPcache, Redis, full-page cache), and CDN deployment to reduce geographic latency.
What are render-blocking resources and how do I fix them?
Render-blocking resources force the browser to pause page construction until they are fully downloaded and processed — keeping the screen blank while they load. CSS blocks rendering because the browser needs a complete style picture before painting. JavaScript blocks HTML parsing unless it carries async or defer. Fixes per Google's render-blocking guide: inline critical above-the-fold CSS in the HTML <head> and load the full stylesheet asynchronously using the rel="preload" technique; add defer to all first-party scripts and async to independent third-party scripts. Use the Lighthouse "Eliminate render-blocking resources" Opportunity to identify which specific files are blocking and how many milliseconds each adds.
What replaced FID in Core Web Vitals?
Interaction to Next Paint (INP) officially replaced First Input Delay (FID) as a Core Web Vital in March 2024, as announced in Google's Chrome developer blog. FID only measured delay before the browser began processing the very first interaction. INP measures the complete latency of all clicks, taps, and keyboard interactions throughout the entire page session. Good INP is ≤ 200ms.
What is LCP and how do I improve it?
LCP (Largest Contentful Paint) measures how quickly the largest visible content element renders. Good is ≤ 2.5 seconds per web.dev/lcp. Per the 2025 Web Almanac, only 62% of mobile pages achieve Good LCP — making it the most commonly failed metric. Top improvements: preload the LCP image with fetchpriority="high", serve it in WebP or AVIF, eliminate render-blocking resources, reduce TTFB under 200ms, never apply loading="lazy" to the LCP image (7% of sites still make this mistake), use a CDN with regional edge coverage, and for text-based LCP elements use font-display: swap or optional.
What causes a high CLS score?
The most common causes: images and iframes without declared width and height attributes; dynamic content (ads, cookie banners) injected above existing page content after initial render; web fonts causing FOUT when they swap in; CSS animations using layout-triggering properties (top, margin) instead of GPU-composited transform. The CLS score is calculated by multiplying the impact fraction (fraction of viewport the shifted element occupied) by the distance fraction (fraction of viewport height it moved). Cookie consent banners are the most common CLS source on European-facing sites. See web.dev/cls.
How do Core Web Vitals interact with other ranking factors?
Core Web Vitals are one of hundreds of signals in Google's ranking algorithm. Google's Page Experience documentation is explicit that content quality, relevance, and E-E-A-T come first. Good CWV will not rescue thin content or compensate for weak links. But poor scores can hold back a page that would otherwise rank well — particularly as more competitors improve. Ahrefs' CWV analysis across millions of URLs found pages in positions 1–3 had consistently higher CWV pass rates than those in positions 6–10, even controlling for domain authority. Think of CWV as removing a potential drag, not as a differentiator.
What is the difference between Gzip and Brotli compression?
Both are lossless algorithms for text-based assets (HTML, CSS, JavaScript, JSON, SVG). Brotli achieves 15–26% better compression ratios than Gzip per Google's original Brotli publication, with ~97% browser support in 2026 per Can I Use. Enable Brotli as primary, Gzip as fallback. Never compress already-compressed binary formats like JPEG, WebP, AVIF, or WOFF2.
What image format should I use in 2026?
WebP for all photographs — 25–35% smaller than JPEG at equivalent quality per Google's WebP study, ~97% browser support. AVIF for maximum compression (40–55% smaller than JPEG) via the HTML <picture> element with WebP fallback, per Google's AVIF research. SVG for all logos, icons, and line art. Add loading="lazy" to below-fold images and fetchpriority="high" to the LCP hero image. Convert your existing image library with IndexCraft's free Image Converter tool.
How do I optimise web font loading for page speed?
Four steps in priority order (per Google's font best practices guide): (1) Add font-display: swap to all @font-face declarations; (2) Add rel="preconnect" hints for font CDN origins; (3) Self-host fonts on your own domain to eliminate cross-origin connection overhead entirely; (4) Subset fonts to only the Unicode ranges your site uses, reducing file size 60–80% for single-language sites using pyftsubset.
How should I handle third-party scripts?
Audit everything first: for each script ask whether it is actively used and contributes to a measurable business outcome. Remove anything that cannot pass that test — no configuration makes a script as fast as not loading it. All retained scripts must use async or defer — never synchronous in <head>. Delay non-essential scripts (chat widgets, heatmaps) until after the user's first interaction. For heavy embeds like YouTube or Google Maps, implement the facade pattern — a lightweight placeholder that loads the real embed on click, reducing associated load from over a second to under 50ms.
How do I measure Core Web Vitals for my site?
Use Google Search Console as your starting point for site-wide field data. Use PageSpeed Insights for per-page field and lab data. Use the Web Vitals Chrome Extension for real-time readings while browsing your own site. Use Lighthouse in Chrome DevTools for in-depth diagnostics. Use WebPageTest for waterfall analysis and real Moto G Power mobile device testing. Use the CrUX Dashboard in Looker Studio for historical trend tracking at origin or URL level. All tools are free.
Does the 75th percentile rule apply to all three Core Web Vitals?
Yes. For a URL to receive an overall Good assessment, at least 75% of real user visits must score Good on each of LCP, INP, and CLS individually, as confirmed in Google's Core Web Vitals developer documentation. If any single metric fails at the 75th percentile, the URL fails overall regardless of how strong the other two are. This means you must specifically improve the experience for your slowest users — not just your average user.
Are Core Web Vitals the same for mobile and desktop?
The same three metrics and thresholds apply to both, but Google measures and reports them separately. Only 48% of mobile websites pass all three versus 56% on desktop per the HTTP Archive Web Almanac 2025. Since Google uses mobile-first indexing (universal since July 2019), mobile Core Web Vitals are the most critical scores to optimise.
How long before Core Web Vitals improvements show in rankings?
Google updates CrUX on a rolling 28-day window per Google's CrUX methodology documentation — improvements today take roughly four weeks to fully show in Search Console. Ranking changes typically follow within one to two crawl cycles — usually two to eight weeks. Allow a full 90 days before a definitive assessment. There is no way to accelerate the CrUX update window; you cannot request a cache refresh.
Does page speed affect Google AI Overviews and AI search?
Based on citation pattern analysis across 47 site launches tracked at IndexCraft since Google AI Overviews launched globally in May 2024, pages with Good Core Web Vitals field data — especially LCP under 2.5s and TTFB under 200ms — show higher rates of citation in AI Overviews compared to structurally similar content on slower origins. Good CWV is considered table stakes for any site targeting AI search visibility in 2026.
What is the ideal mobile page load time target for 2026?
Google's Core Web Vitals Good LCP threshold is under 2.5 seconds. A mobile PageSpeed Insights score above 80 with Good LCP and INP field data is the 2026 benchmark. Per the HTTP Archive Web Almanac 2025, only 48% of mobile sites currently pass all three Core Web Vitals — passing with comfortable margins represents a meaningful competitive advantage in most niches.
What is a performance budget and how do I enforce one?
A performance budget is an agreed set of limits your team will not exceed — for example, initial JS bundle under 150KB compressed, mobile PageSpeed score above 80, and fewer than 5 third-party requests per page. The point is having automated tooling that catches regressions before they ship. Enforce budgets via Lighthouse CI integrated into your CI/CD pipeline — it runs an audit on every pull request and fails the build if any configured threshold is exceeded. More detail in Google's Performance Budgets 101 guide.
📚 Primary Sources & References
- HTTP Archive Web Almanac 2025 — Performance chapter (July 2025 CrUX data)
- HTTP Archive Web Almanac 2025 — SEO chapter
- HTTP Archive Web Almanac 2025 — CMS chapter
- HTTP Archive Web Almanac 2025 — Ecommerce chapter
- HTTP Archive Web Almanac 2025 — JavaScript chapter
- HTTP Archive Web Almanac 2025 — Page Weight chapter
- HTTP Archive Web Almanac 2025 — Fonts chapter
- HTTP Archive Web Almanac 2025 — Third Parties chapter
- Google Web Vitals documentation — web.dev/vitals
- Defining the Core Web Vitals metrics thresholds — web.dev
- Google Core Web Vitals developer documentation
- Google Page Experience documentation
- Chrome User Experience Report (CrUX) methodology
- Google Chrome blog — INP becomes a Core Web Vital (March 2024)
- Think with Google / SOASTA mobile speed study
- Deloitte Digital — Milliseconds Make Millions
- Google web.dev — Optimize LCP
- Google web.dev — Optimize Long Tasks
- RFC 9113 — HTTP/2 specification
- RFC 9114 — HTTP/3 specification
- W3Techs — CMS Market Share
- Kinsta — WordPress Hosting Performance Benchmarks
- Kinsta — Cloudflare APO Benchmark Analysis