Advertisement

Users do not experience your page as a single load time; they experience a sequence — blank screen, first content, something they can read, something they can click. "Slow" is really a story about how long each of those steps takes, and which one your particular page gets wrong. Optimising the wrong step is wasted effort, so the first job is knowing which step hurts.

The good news is that the industry has converged on a small set of metrics that map well onto how a page actually feels, and browsers hand them to you for free. Learn those and you can stop guessing.

The three vitals worth your attention

Largest Contentful Paint measures how long until the main content — usually the biggest image or heading — appears. It is the closest single number to "when does this page feel loaded". A slow LCP almost always traces back to a heavy image, a slow server response, or render-blocking resources at the top of the page.

Interaction to Next Paint captures responsiveness: when the user taps or types, how long until the page visibly reacts. And Cumulative Layout Shift measures visual stability — how much the page jumps around as it loads, the infuriating effect where you go to tap a button and an ad pushes it away. Together these three describe loading, responsiveness and stability.

Advertisement

The usual culprits

Images are the number one weight on most pages: unsized, uncompressed, and far larger than the space they display in. Serving appropriately sized, modern-format images and giving them explicit dimensions fixes both slow LCP and layout shift at once. It is the highest-return change on the majority of sites.

JavaScript is the second: large bundles that must download, parse and execute before the page becomes interactive block the main thread and wreck responsiveness. Shipping less script, splitting it so only what a page needs loads, and deferring non-essential work are the levers. A third culprit — a slow server or database query — sits underneath everything, because nothing renders until the first bytes arrive.

Measure real users, not just your laptop

Your development machine on fast office internet is the best case, not the typical case. Lab tools that simulate a mid-range phone on a slower connection give a truer picture, and field data collected from actual visitors tells you what your real audience experiences across their real devices.

The workflow that works: measure to find the worst step, fix the biggest single cause of it, measure again. Chasing a perfect score on a synthetic test matters far less than moving the metric your real users feel. Performance is iterative, and a few targeted fixes usually recover most of the lost time.

Advertisement

LCP: what actually counts as the largest element, and why that changes over a page's life

Largest Contentful Paint measures the render time of the largest image or text block visible within the viewport, and the specific element it measures is not fixed for a page's entire load — as more content streams in, a larger element can appear and become the new LCP candidate, replacing whatever was previously the largest, which is why LCP is reported as the final, largest element once the page has settled rather than the first large thing to render. A common, avoidable LCP problem is a hero image loaded without any priority hint, competing for bandwidth with dozens of lower-priority resources the browser has no reason to know matter less.

INP: the successor metric measuring responsiveness after the page has loaded

Interaction to Next Paint replaced First Input Delay as the standard responsiveness metric specifically because FID only measured the delay before the browser began processing the very first interaction, saying nothing about how long the resulting visual update actually took, or about any interaction after the first one — INP instead measures the full latency of every interaction throughout a page's lifetime and reports the worst one, capturing exactly the kind of janky, unresponsive click that FID's narrower definition could miss entirely. A page can post an excellent FID while still feeling sluggish to actually use, which is the specific gap INP was introduced to close.

Advertisement

CLS: why layout shift is measured as a score, not a binary pass or fail

Cumulative Layout Shift accumulates a numeric score across every unexpected layout movement during a page's life, weighting each shift by both how much of the viewport moved and how far it moved, rather than simply counting the number of shifts — this is why a single large, jarring shift and several small, barely noticeable ones can produce a similar score, and why the fix is not merely 'have fewer shifts' but specifically reserving space for anything whose final size is not yet known when it starts rendering, such as an image with no explicit width and height attribute or an ad slot that resizes once its content actually loads.

Why lab data and field data can disagree, and which one to trust for which decision

A score measured in a controlled lab environment, run once under fixed network and device conditions, is reproducible and useful for debugging a specific change, but it does not reflect the actual range of real devices and network conditions actual visitors use — field data, collected from real users' actual browsers via the Chrome User Experience Report or a site's own real-user-monitoring setup, reflects true visitor experience but is noisier and cannot be attributed to a specific isolated change as cleanly. Using lab data to debug and verify a specific fix, and field data to confirm that fix actually improved the metric for real visitors afterward, uses each source for what it is actually good at rather than treating either as sufficient on its own.

Why TTFB is a server-side metric hiding inside a client-side scorecard

Time to First Byte measures how long the browser waits before receiving even the first byte of the response, which is almost entirely a function of server-side processing time and network latency to the server, not anything about the page's own frontend code — a page with an excellent LCP and CLS can still feel slow overall if TTFB is high, because every other metric in this article can only start its own clock once the response has actually begun arriving, which is why a genuinely comprehensive performance investigation checks server response time first, before assuming a slow page is necessarily a frontend problem.

Why field data segments matter more than a single aggregate number

A single averaged or even median Core Web Vitals number across all visitors can hide a real, meaningful problem affecting a specific segment — mobile users on a slow connection, visitors in a specific region far from the nearest server — while the aggregate looks perfectly acceptable; breaking field data down by device type, connection speed, and geography, rather than trusting one blended number, is what actually reveals whether a specific, addressable segment is having a meaningfully worse experience than the overall number would ever suggest on its own.

Why a fast page can still feel slow, and vice versa

Perceived speed and measured speed diverge in specific, well-documented ways — a page that shows a skeleton loading state immediately, even while the real content is still fetching, is frequently perceived as faster than a page with a slightly better raw LCP number but a blank screen right up until content suddenly appears, because a visible, immediate response to a user's action matters to perception independently of the raw timing numbers underneath it, which is why perceived performance is worth designing for deliberately, not assumed to follow automatically from optimizing the measured metrics alone.

Why mobile performance deserves its own dedicated measurement, not an assumption

A page tested only on a developer's own fast desktop machine over a fast office connection can look perfectly fine while performing considerably worse for the actual majority of visitors on a mid-range phone over a real mobile network — testing explicitly under throttled, mobile-representative conditions rather than assuming desktop results generalize is what actually reveals whether the metrics discussed throughout this article hold up for the visitors most likely to be affected by a slow page in the first place.

Why the same page can score differently minute to minute in a lab test

A lab test run twice in a row against the identical, unchanged page can still produce slightly different numbers, because the testing machine's own CPU load, background processes, and network conditions vary run to run even under nominally controlled settings — this is precisely why serious performance testing runs several iterations and looks at the median rather than trusting any single run, treating one measurement in isolation the way one would treat any noisy real-world signal rather than an exact, deterministic number.

Why a single slow third-party script can dominate every other optimization

A team can spend weeks optimizing its own first-party code — compressing images, splitting bundles, tuning cache headers — only to have a single slow third-party analytics or advertising script continue dragging every Core Web Vital down regardless, since that script is entirely outside the team's own control and update schedule; auditing third-party scripts specifically, and being willing to remove or defer ones that are not earning their real performance cost, is frequently a higher-leverage fix than another round of first-party optimization once the easy first-party wins have already been captured.

Why fixing the metric directly sometimes misses the actual user complaint

It is possible to improve every Core Web Vital measurably while users continue reporting the page feels slow, if the actual friction they are experiencing is something the standard metrics do not directly capture — a slow search results update, a laggy dropdown, a delay specific to one interaction the aggregate page-load metrics were never designed to isolate; treating user-reported slowness as its own signal worth investigating directly, rather than assuming it must already be reflected in whichever standard metric is being tracked, catches problems the standard metric set simply was not built to measure.

Why alerting on Core Web Vitals needs its own sensible thresholds, not generic ones

Google publishes general guidance for what counts as a 'good', 'needs improvement', or 'poor' score for each Core Web Vital, but a site's own alerting thresholds are worth tuning against its own historical baseline and actual business impact rather than adopting the generic guidance uncritically — a site that has always scored in the 'needs improvement' range for a metric that does not meaningfully affect its specific user behavior may reasonably deprioritize chasing the generic 'good' threshold in favor of a metric more directly tied to its own measured business outcomes.

Why the highest-return fix is usually the simplest, most boring one

Teams new to performance work often reach first for the most sophisticated available technique — a custom rendering strategy, an elaborate build pipeline change — when the actual highest-return fix on a given page is frequently something unglamorous: compressing an oversized image, removing an unused third-party script, or fixing a missing width and height attribute, all of which cost little effort and often move the needle more than a sophisticated technique applied to a page that never had the underlying problem that technique was built to solve.