What Happens When You Open a Website
URL to pixels: resolution, connection, request, streaming HTML, DOM and CSSOM, style, layout, paint, composite — and what blocks what.
The intent, the obvious build, and why it breaks
Every lesson starts where the work starts: someone wanted an outcome, and the first implementation that comes to mind has a problem.
Between pressing Enter and seeing content, what exactly happens, and which step is the one holding me up?
A person taps a link. They expect to see the thing they came for — not a spinner, not a blank page, not a layout that jumps once the fonts arrive.
The browser downloads the page and shows it. If it is slow, the page must be too big, so make the page smaller.
Total bytes and time to first content are only loosely related. A 2 MB page whose critical resources arrive first can render sooner than a 300 KB page that blocks on a stylesheet from a third-party origin.
- Total bytes and time to first content are only loosely related. A 2 MB page whose critical resources arrive first can render sooner than a 300 KB page that blocks on a stylesheet from a third-party origin.
- Nothing renders until at least one stylesheet has been parsed, so a single slow CSS file delays first paint no matter how small the HTML is (Render-Blocking Resources).
- A synchronous
scriptin the head stops parsing at that point — the parser has to assume the script might write to the document (Why a Script Tag Stops the Parser). - The first byte can be late for reasons entirely outside the page: DNS resolution, connection setup, TLS negotiation, or the server thinking (Reading a Network Waterfall).
- "Make it smaller" is not actionable. "The font file is discovered late because it is referenced from a stylesheet that is itself discovered late" is.
What is actually happening
In the browser, not in the framework.
- Resolve. The hostname becomes an address, possibly via cache, possibly via a full recursive lookup (Following One Lookup Through Every Cache in Networking).
- Connect. A TCP connection or a QUIC session is established, then TLS is negotiated. On a cold connection this is several round trips before a single byte of your page moves (The Three-Way Handshake in Networking).
- Request. The browser sends the request, with cookies and cache validators attached automatically.
- Respond. The server returns HTML. The browser does not wait for all of it — the parser starts on the first chunk (Streaming HTML).
- Parse. Bytes become tokens become a tree. Along the way the parser encounters references to CSS, JavaScript, images and fonts, and dispatches requests for them, aided by a preload scanner that looks ahead (The Preload Scanner).
- Build the CSSOM. Stylesheets are fetched and parsed. CSS is render-blocking: the browser will not paint content it might have to restyle immediately.
- Style. For each element, the cascade produces one computed value per property (Style Calculation).
- Layout. Computed styles plus the tree produce geometry: a box, a position and a size for everything that has them (The Box Model).
- Paint. Geometry plus style produce ordered drawing commands.
- Composite. Painted layers are combined, potentially on another thread, and handed to the display (Compositing Layers).
What this makes the browser do
And which of it is avoidable.
- Speculative work: the preload scanner requests subresources it can see ahead in the byte stream even while the main parser is blocked on a script.
- Re-work: a late stylesheet, a late font or a late image without dimensions can force style, layout and paint to run again over content that was already on screen (Visual Stability).
- Prioritisation: the browser assigns priorities to requests and will delay a low-priority image to get a render-blocking stylesheet sooner.
- Incremental rendering: the browser can and does paint a partial document. The first paint is not the end of parsing.
The whole sequence, once
This is the domain's spine. Almost every other lesson is a zoom into one of these boxes, and almost every loading question is answered by naming which box is waiting and on what.
Read it as a dependency graph rather than a checklist: parsing depends on bytes, style depends on the CSSOM, layout depends on style, paint depends on layout. Anything that delays an early stage delays everything downstream, which is why a single blocking resource on a slow origin can dominate a page that is otherwise well built.
What blocks what
The useful question is never "how long did the page take". It is "what was the browser unable to do, and why". Four blocking relationships explain most of it.
Note that these are different in kind. A render-blocking stylesheet is the browser deliberately refusing to show you content it might have to restyle. A parser-blocking script is the browser being unable to continue, because the script might change the document it is in the middle of building. Conflating them leads to fixes aimed at the wrong stage.
- 1Network blocks everything
Nothing can start before the first byte of HTML arrives.
fails by Redirect chains, slow server response, or a cold connection to a third-party origin on the critical path.
- 2CSS blocks rendering
The browser will not paint content it may immediately have to restyle.
fails by A large or slow stylesheet, or one on a third-party origin requiring its own DNS, connection and TLS.
- 3Synchronous scripts block parsing
The parser stops, because the script may modify the document at this point.
fails by A
scripttag in the head with nodeferorasync, for code that did not need to run then. - 4Scripts wait on CSS
A script that could read computed style must wait for pending stylesheets first.
fails by The surprising case: a small inline script delayed by a large stylesheet it never touches.
Each has a different fix. Only the first is about bytes.
Reading a waterfall
A waterfall is the sequence above, drawn per resource. What you are looking for is not the longest bar but the staircase: a resource that could not start until another finished, because that is a dependency the page structure created and that you may be able to remove.
The timeline below is schematic and in relative units. Real numbers come from the Network panel or from field data; the shape is what transfers.
- DNS + connect + TLS — Pure round trips. Nothing about the page can change this except not needing the origin at all.
- HTML (streams) — Parsing starts on the first chunk, not at the end of the bar.
- CSS (render-blocking) — Discovered by the parser; nothing paints until it is parsed.
- Blocking script — Parser stopped here. The gap in parsing is the cost.
- Font (late) — Discovered inside the CSS, so it could not start until the CSS arrived — a staircase.
- Reflow on font swap — Text already read by the user moves. This is where visual instability comes from.
The font bar is the lesson: it starts late not because it is large but because it was discovered late. Moving discovery earlier is worth more than making the file smaller.
How to build it
Most important first.
- Get the HTML to the browser early and let it stream. Anything that delays the first byte delays every subsequent step, and no client optimisation can recover it (Server-Side Rendering).
- Make the critical path short: the fewest resources that must arrive before meaningful content can paint, discovered as early as possible (The Critical Rendering Path).
- Do not block the parser with scripts that do not need to run before content.
deferandtype="module"exist precisely for this (`defer`, `async` and `type="module"`). - Reserve space for anything that arrives late — images, ads, embeds, fonts — so its arrival does not move content that a person is already reading (Visual Stability).
- Use resource hints deliberately and sparingly.
preconnectfor an origin you will certainly use early is a round-trip saved; ten speculative hints are contention (Resource Hints).
Keyboard, focus, semantics, announcement
A required field on every lesson in this domain, not a section added when there is room.
- Content that renders progressively is announced progressively. A screen reader reading a partially loaded page is normal, and it is a reason to emit content in a meaningful order rather than in whatever order it is convenient to render.
- Layout shifts are worse than annoying for some users: they move the target a switch or eye-tracking user was aiming at, and they can move the reading position of a screen-magnifier user without warning.
- A blank page while JavaScript loads is unnavigable by every assistive technology. Server-rendered content is available to assistive technology at first paint, which is a large part of why the strategy choice is an accessibility decision too (Client-Side Rendering).
- A visible, well-ordered focus target after navigation matters more than a fast paint for keyboard users. If focus stays on a stale element, they have no way to reach the new content (Focus Management).
What can go wrong
- Render-blocking CSS on a slow third-party origin: first paint waits on a DNS lookup, a connection and a TLS handshake to a host you do not control.
- A synchronous script in the head that only sets an analytics variable, delaying the parser for the whole round trip.
- Fonts that arrive late and swap, reflowing text that had already been painted, or hide text entirely until they arrive.
- Images without intrinsic dimensions, which take up zero space until decoded and then shove everything below them down the page.
- A redirect chain before the HTML: every hop is a full round trip before parsing can begin.
- Subresource responses arrive in an order the browser chooses, not the order they appear in the document. Anything that depends on two of them being present must express that dependency rather than assume it.
- A font and the text it styles race: which wins determines whether the user sees a flash of fallback text, a flash of invisible text, or neither.
- Everything in this sequence happens over an origin. Loading a subresource from a third-party origin extends the trust boundary of the page to that origin (Third-Party Scripts and the Supply Chain).
- The connection step is where transport security is established. Content loaded insecurely into a secure page is blocked or downgraded by the browser.
- Cookies are attached automatically to requests that match their scope, which is the mechanism behind cross-site request forgery (Cross-Site Request Forgery).
- A Content-Security-Policy header delivered with this HTML constrains everything that follows in it, which is why it must be sent by the server rather than added by script (Content Security Policy).
- "The page is slow because it is big." Size matters, but blocking structure and discovery order usually matter more.
- "Nothing renders until the page has fully loaded." The browser paints incrementally and always has;
loadfires long after the user can see and use content. - "HTTPS is only about encryption." The handshake is also part of your critical path, which is a performance reason to reuse connections, not a reason to avoid TLS.
- "First paint is the goal." Painting a skeleton fast and becoming usable slowly is a measurable regression in every metric a user actually feels (Interaction Responsiveness).
Measuring it, and what changes in the field
- The Network panel waterfall shows the dependency structure: what was requested when, what was queued, what was blocked, and what the browser was waiting on at each moment (Reading a Network Waterfall).
- The Performance panel shows the parse, style, layout, paint and composite work interleaved with script on the main thread.
- Loading and visual-stability field metrics tell you whether the improvement was real for users or only for your machine (Vitals in the Field).
- On a high-latency network, round trips dominate and the number of sequential dependencies matters far more than bytes. Removing one blocking hop can beat halving the payload.
- On a slow device, parse and script execution dominate, and the same waterfall produces a completely different profile.
- On a repeat visit, the HTTP cache and service worker can remove most of this sequence, which is why first-visit and repeat-visit performance are two separate problems (Caching Strategies).
- Inlining critical CSS removes a round trip but makes that CSS uncacheable and grows every HTML response. It is a first-visit optimisation paid for on every subsequent one.
- Server-rendering gets content to the browser sooner but moves cost and complexity onto a server you now have to run and scale (Server-Side Rendering).
- Preloading a resource raises its priority at the expense of everything else in flight. Preloading everything is the same as preloading nothing, with extra contention.
Where this applies
Frontend advice ages badly and fragments across engines. These labels say what each claim is specific to, and where a different browser, device or framework would differ.
- GENERALThe stage order — resolve, connect, request, parse, style, layout, paint, composite — is common to every modern browser, because it follows from the specifications rather than from an implementation.
- SIMPLIFIEDReal engines overlap and speculate heavily: parsing continues past a blocked script for resource discovery, layout can be partial, paint and composite can be skipped for offscreen content. The linear ordering here is a teaching model that predicts blocking correctly but understates concurrency.
- NETWORK-SPECIFICOn HTTP/2 and HTTP/3 the per-request cost of an extra file is much lower than on HTTP/1.1, so advice about bundling everything into one file to reduce request count is protocol-dependent and now often counterproductive (Bundlers Compared).
Where the depth lives
This domain teaches the browser-side mechanism and hands the rest off.
- — Distributed Systems — why the first byte is late is often a question about a server, a queue and a cache that live nowhere near the browser.