Skip to main content
← Back to blogs

Core Web Vitals, PageSpeed, and SEO: a developer’s guide to web performance

By AntonioGitHub ↗LinkedIn ↗
Web DevelopmentCodingNext.js

A from-first-principles guide to web performance: what Core Web Vitals (LCP, INP, CLS) actually measure, how PageSpeed scoring works, and how it all connects to SEO and Google ranking.

If you have ever run your site through PageSpeed Insights, seen a number like 63, and felt a vague dread without knowing what to fix, this guide is for you. We are going to build the whole picture from the ground up: what web performance actually means to a browser, what Google measures, why it measures those specific things, how it connects to search ranking, and how to read a report so you fix the right thing instead of chasing noise.

Performance is just a stopwatch on how a browser loads a page

When someone opens a page, the browser runs a sequence of jobs: it requests the HTML, waits for the first byte, parses it, downloads the CSS and JavaScript and fonts it finds, paints the first pixels, paints the largest meaningful element, becomes interactive, and finally settles. Every performance metric is just a stopwatch on one of those moments. Once you see it that way, the jargon stops being scary.

Two kinds of data, and people constantly confuse them

Before any metric makes sense, you need to know there are two separate worlds of performance data.

Lab data (synthetic). This is what Lighthouse and the PageSpeed score give you: a robot loads the page once, on a simulated mid-range phone, on a throttled Slow 4G connection. It is reproducible and perfect for debugging, because you can change one thing and re-measure. But it is one load, on one fake device.

Field data (real users). This is CrUX, the Chrome User Experience Report, collected from real Chrome users over a rolling 28-day window. It is messy and slow to update, but it reflects reality.

Here is the part that matters for SEO: Google ranking uses field data, not your Lighthouse score. The synthetic number is a debugging tool. A brand new or low-traffic site often shows "No Data" for field data simply because not enough real people have visited yet. So use the lab score to find and fix problems, and remember the field data is what eventually counts.

The three Core Web Vitals, explained properly

Core Web Vitals are Google’s short list of "does this page feel good to a human." There are three, and each maps to one of those loading steps.

LCP: Largest Contentful Paint (loading)

LCP measures how long until the biggest visible piece of content appears: usually a hero image or a large heading. A page feels loaded to a human when the main thing they came for is on screen. Good is under 2.5 seconds on mobile.

LCP has phases, and the report breaks them down: time to first byte, load delay, load time, and render delay. This breakdown tells you which fix will help. A large load time means the resource (often an image) is too big. A large render delay means something is blocking the paint even though the content is ready.

A very common, self-inflicted LCP problem: revealing your hero with a JavaScript animation that starts it at opacity zero and fades it in. JavaScript only runs after a pile of code downloads and executes, which on a throttled phone can be several seconds. So the largest element sits invisible until then, and the browser times that late reveal as the LCP, even though the content was in the HTML the whole time. The lesson: an animation that starts your largest element hidden will wreck your LCP. Fade-in-on-load and reveal-on-scroll are beautiful, and they are also the most common LCP wound. If you must animate the hero, do it with CSS (which runs at first paint) and avoid starting it fully transparent.

INP: Interaction to Next Paint (responsiveness)

INP measures how quickly the page responds when you tap, click, or type. It replaced an older metric called FID in March 2024, because FID only measured the very first interaction, which was too forgiving. Good is under 200 milliseconds.

The enemy of INP is a busy main thread. Browsers run JavaScript on a single thread, the same one that handles taps and paints. If a big chunk of JavaScript is hogging it when the user taps, the tap waits its turn. The fixes: ship less JavaScript, break long tasks into smaller ones, and defer non-essential work (analytics, chat widgets, anything third-party) to idle time so it does not compete with the page coming alive. In the lab, the related number is Total Blocking Time, which is why Lighthouse weights it heavily.

CLS: Cumulative Layout Shift (visual stability)

CLS measures how much things jump around while the page loads. You have felt it: you go to tap a link, an image above finishes loading, everything shoves down, and you tap the wrong thing. Good is under 0.1 (it is a unitless score, not time).

The causes are almost always images and embeds without reserved dimensions, or fonts that swap and resize text. The fix is mechanical: give every image and video an explicit width and height (or an aspect ratio) so the browser reserves the space before the file arrives. CLS is the easiest vital to get to a perfect score.

The other numbers, and how the score is actually built

The overall Lighthouse Performance score is a weighted blend of five lab metrics. The weights tell you where points come from:

  • Total Blocking Time: 30 percent
  • Largest Contentful Paint: 25 percent
  • Cumulative Layout Shift: 25 percent
  • First Contentful Paint: 10 percent
  • Speed Index: 10 percent

First Contentful Paint is the time to the first pixel of any content. Speed Index measures how quickly the page visually fills in. Time to First Byte is not in the score directly, but it is the foundation under everything: a slow server delays every other metric.

Two consequences. First, TBT and LCP together are more than half the score, so start there. Second, the report lists many diagnostics marked "Unscored." That word matters: an unscored item does not directly lower your number. It is informational, and it can feed indirectly into a metric, but you can fix every unscored item and watch your score not move at all. Read the "Unscored" label before you spend an afternoon on something like a legacy-JavaScript warning that modern browsers never even download.

How this actually connects to SEO

Does this make Google rank you higher? The honest answer has three parts.

One: page experience is a real but modest ranking signal. It is a tiebreaker, not a trump card. If your content is the best answer, a mediocre LCP will not bury you. If two pages are otherwise equal, the faster, more stable one can win. Think of performance as removing a handicap, not buying rank.

Two: it is measured on real users and mobile first. Google evaluates the mobile experience using field data, not your synthetic score.

Three: the indirect effects are arguably bigger than the direct ranking factor. A fast page keeps people from bouncing, a stable page does not make them rage-tap, and content that paints in one second instead of six actually gets seen and crawled. Those effects compound. So optimize performance because real humans and the crawler have a better time, and ranking benefits follow as a second-order effect.

How to read a report and fix the right thing

A reliable loop:

  • Run the mobile test and look at field data first if it exists. That is your real grade; the lab score is your debugger.
  • Find the metric costing the most points. Given the weights, it is almost always LCP or TBT.
  • For LCP, open the LCP breakdown and read the phases. Time in load means a resource is too big or fetched too late. Time in render means something is blocking the paint.
  • Watch the filmstrip. PageSpeed shows frame-by-frame thumbnails of the load. You can literally see when the main content appears. If it appears early but LCP is recorded late, you have a render-delay problem (a font swap, a late animation, a compositing effect).
  • Change one thing, re-measure. Synthetic tests are reproducible, so fix one variable at a time and watch the number move. Note that throttled-mobile runs are noisy, so take the median of two or three runs rather than trusting a single one.

The highest-leverage fixes, roughly in order

Make the LCP element paint immediately. If it is an image: serve a modern format (WebP or AVIF), size it to how it is actually displayed (do not ship a 2000px image into a 600px slot), and never lazy-load it. If it is text: do not hide it behind a JavaScript entrance, and make sure the web font is not blocking it (use font-display swap and a size-matched fallback).

Cut and defer JavaScript. Every kilobyte is downloaded, parsed, and executed on the main thread, which hurts TBT and INP. Defer third-party scripts so they load during idle time, not on the critical path, and remove what you do not use.

Reserve space for everything. Explicit width and height on every image and embed makes CLS a non-issue.

Compress and right-size images. Images are usually the biggest bytes on a page, and modern formats plus correct dimensions routinely cut their weight by 70 percent or more. If your image CDN can negotiate formats automatically, turning that on is often a one-line change.

Get your server fast. Good time to first byte through caching and a CDN lifts every other metric.

Avoid the white flash. If your design has a dark background, set it as an inline style on the page so the very first frame is on-brand instead of white while the stylesheet loads.

The honest part about diminishing returns

If a site is a heavily animated showpiece (smooth scrolling, canvas effects, scroll-driven reveals, a custom cursor), throttled-mobile scores will fight it, because those effects are exactly the main-thread work the score penalizes. You can improve a lot by fixing the structural issues above. But the last few points often mean trading away the very thing that makes the site distinctive, and that is a legitimate product decision, not a failure. A strong score with a design you are proud of beats a perfect score on a page that looks like everyone else.

The one-paragraph summary

Performance metrics are stopwatches on the steps a browser takes to load a page. Core Web Vitals pick the three humans feel: how fast the main content appears (LCP), how fast the page responds to taps (INP), and how much it jumps around (CLS). The Lighthouse score is a debugging tool, weighted heavily toward TBT and LCP, while real ranking uses field data and treats experience as a modest tiebreaker. Read the LCP breakdown to know whether to fix loading or rendering, change one thing at a time, fix the scored metrics, ignore the unscored noise, and remember the biggest win is usually to stop making the browser wait for JavaScript to show content it already has.

Related posts