Page speed and Core Web Vitals optimisation
The causes behind LCP, INP and CLS, image and font loading that actually helps, render-blocking resources, and how to read lab data against field data.
What each metric punishes
| Metric | Good | Needs work | Main causes |
|---|---|---|---|
| LCP | 2.5 s or less | over 4.0 s | Slow server response, a render-blocking resource, a late hero image |
| INP | 200 ms or less | over 500 ms | Long tasks on the main thread, heavy third-party scripts, large DOM updates |
| CLS | 0.1 or less | over 0.25 | Images and embeds without dimensions, late-injected banners, font swap reflow |
All three are measured on real visits at the 75th percentile, split by device. A green desktop score with a red mobile score means the problem is the mobile experience: slower CPUs, slower networks and more layout pressure.
<!-- the hero image is usually the LCP element: make it discoverable and correctly sized -->
<link rel="preload" as="image" href="/hero.avif" fetchpriority="high" type="image/avif" />
<img src="/hero.avif" width="1200" height="675" alt="Dashboard overview"
fetchpriority="high" decoding="async" />
<!-- everything below the fold: lazy load it, but never the LCP image -->
<img src="/detail.webp" width="800" height="450" loading="lazy" decoding="async" alt="Report detail" />- Reserve space for anything that loads late. Explicit
widthandheightattributes plusaspect-ratioin CSS remove almost all image-driven layout shift. loading="lazy"on the hero image delays the largest paint - the exact opposite of what you want.- Use
fetchpriority="high"on one element only. Applying it everywhere means nothing is prioritised.
Render blocking and interaction cost
<!-- critical CSS inline, the rest deferred -->
<style>/* above-the-fold rules only, under ~14 KB */</style>
<link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'" />
<noscript><link rel="stylesheet" href="/styles.css" /></noscript>
<!-- third-party tags must not block parsing: mark every non-essential
script element with the defer attribute so it runs after parsing -->
<!-- and keep the number of third-party tags as low as you can justify -->
<!-- self-host the font and let text render immediately -->
<style>
@font-face {
font-family: "Inter";
src: url("/fonts/inter.woff2") format("woff2");
font-display: swap;
unicode-range: U+0000-00FF;
}
</style>| Symptom | Diagnosis | Fix |
|---|---|---|
| High INP on one interaction | A long task blocks the response | Break the work up, yield to the main thread |
| LCP stuck around 3 s | Server response dominates | Cache the HTML, add a CDN, remove a slow query |
| LCP high but TTFB low | Late-discovered resource | Preload the LCP image and the critical font |
| CLS spikes on scroll | Late ad or banner injection | Reserve the slot with a fixed container height |
| Mobile much worse than desktop | CPU-bound scripts | Reduce JavaScript, defer third parties |
The cheapest large win is usually deleting third-party scripts. Every tag added for marketing costs main-thread time on every visit, and a single chat widget can cost more than the rest of the page combined.
Lab data versus field data
- Lab data comes from a synthetic run on a fixed device and network profile. It is reproducible, great for debugging a specific regression, and never a proxy for the user experience.
- Field data is real visits over the last 28 days, grouped by URL. It is what any ranking signal uses and it moves slowly - fixing a template takes weeks to show.
- Search Console groups field data by URL group, which points at the template rather than the single page. Fix the template, not the examples.
- Track one metric at a time. Changing images, fonts and third parties in the same release means you learn nothing about which one helped.
⚠️
A single fast test run is not evidence. Score variance between runs on the same page is often larger than the improvement you think you shipped. Compare medians of several runs, and confirm with field data before claiming a win.
FAQ
How much does speed affect ranking?
It is a real but modest factor, and it matters most when everything else is close. The bigger effect is behavioural: slow pages lose visits before they ever become a ranking question.
Should I use a framework that ships less JavaScript?
Ship less JavaScript, but measure it. A render-blocking stylesheet or a slow origin can dominate a page whose framework bundle is already small.
Related
Technical SEO and measuring it SEO for JavaScript-rendered sites
Last refreshed 2026-09-18.