The Loading Story: TTFB, FCP, LCP
A page loads in a chain, and every visible metric waits on the link before it. Read the chain in order, from the first byte off the server to the largest paint on screen, and a slow page stops being a mystery. You learn to fix the earliest weak link instead of chasing the symptom.
Time to First Byte
Time to First Byte, or TTFB, is the time from starting navigation until the browser receives the first byte of the server's response to the main document. Nothing has painted yet. It sums, in order, redirect time, service-worker startup, DNS lookup, the TCP and TLS connection, the request being sent, and server processing up to that first byte. Because it bundles connection setup and redirects, it is broader than pure server response time.
TTFB sits in front of every visible metric. First paint and largest paint cannot happen until the document arrives, so a slow first byte pushes everything downstream. It is not a Core Web Vital, but it is often the hidden reason a page's LCP is poor. The threshold is diagnostic, not pass or fail: good is under 800 ms, and if TTFB is already under 800 ms while LCP stays poor, the problem is downstream in how the page renders. Server health caps crawl and TTFB →
To improve it, put a CDN in front, cache the HTML at the edge or reverse proxy, speed the origin with indexed queries and an application cache, kill redirect chains, and speed the connection withTLS 1.3 and a modern protocol. Caching and CDN feed TTFB →
First and largest paint
Two paint metrics measure when the page starts to feel alive. First Contentful Paint, or FCP, is the moment the first DOM content renders and the screen stops being blank: a bit of text, an image, anything. Good is under 1.8 s. It tells the visitor something is happening.
Largest Contentful Paint, or LCP, is the render time of the largest image or text block visible in the viewport, measured relative to when the page started loading. It is usually the hero image, a big heading, or the first large block of text, and it marks the moment the page feels loaded. LCP is a Core Web Vital: good is 2.5 s or less at the 75th percentile of real loads. FCP says the page began; LCP says the main content is there.
FCP marks when the screen stops being blank. LCP marks when the main content finishes painting. Grade LCP at the 75th percentile, so your slower visits set the number, not your best-case demo.
The four parts of LCP
LCP is not one number to poke at blindly. It breaks into four parts you can measure and attack separately.
- TTFB: the time to that first response byte, as above.
- Resource load delay: the gap until the browser even starts fetching the LCP resource. A late-discovered hero image lives here.
- Resource load duration: how long the LCP resource takes to download.
- Element render delay: the time from the resource being ready until it actually paints.
The goal is simple to state: most of LCP should be load duration, not the delays. If the two delay parts dominate, you have a discovery or a render problem, not a slow download. Splitting LCP this way tells you which of the four to fix first instead of guessing.
How to improve LCP
Start by making the LCP resource discoverable early. Put a real <img> in the initial HTML so the browser's preload scanner finds it, mark it fetchpriority="high", and preload it if it is discovered late. Do not lazy-load the hero image: lazy-loading is for content below the fold, and applying it to the largest paint element delays the very thing LCP measures. Image dimensions and formats →
Next, cut what blocks rendering. Render-blocking CSS and JavaScript hold up the first paint, so inline the critical CSS and defer the rest. Shrink the resource itself: convert to AVIF or WebP, serve responsive sizes with srcset, and push it through a CDN so it arrives from a server near the user. Fix TTFB first, since it is the floor under the whole metric. Finally, reduce element render delay by serving real HTML from the server through SSR or SSG rather than building the content in the browser after the fact.
That is the loading story from first byte to largest paint. A page can load fast and still feel broken if the content jumps around as it arrives, which is the next thing to measure. Visual stability next →