CodeCompiler logo CodeCompiler
← Back to Blog

Concepts

What Really Happens When a Browser Loads a Web Page?

By the CodeCompiler Team · 11 min read

Typing a web address and pressing Enter feels instantaneous — within a second or two, a fully formed page appears, styled and interactive. Behind that simple experience is a remarkably intricate sequence of network requests, parsing, computation, and rendering, all happening in a fraction of a second. Understanding this sequence, often called the critical rendering path, is enormously useful: it explains why some pages feel instant while others feel sluggish, and it's a common topic in technical interviews for web development roles.

Step 1: Turning a Domain Name Into an Address

The moment you press Enter after typing a URL like example.com, the browser needs to find the actual server responsible for that domain. It does this through a system called DNS (the Domain Name System), which works something like a phone book for the internet, translating human-readable domain names into numeric IP addresses that computers use to route network traffic. This lookup is often cached — by your browser, your operating system, or your internet provider — so it doesn't always require a fresh network request, but the very first time you visit a domain, this step has to happen.

Step 2: Establishing a Connection

Once the browser has the server's IP address, it opens a network connection to that server, typically using HTTPS (the secure version of HTTP). This involves a "handshake" process where the browser and server agree on encryption parameters, so that all data transferred between them afterward is encrypted and can't easily be intercepted or tampered with along the way.

Step 3: Requesting and Receiving the HTML

With a connection established, the browser sends an HTTP request asking for the specific page you requested, and the server responds with the HTML document for that page. This HTML arrives as a stream of raw text, and the browser doesn't wait for the entire document to fully arrive before beginning to process it — modern browsers start parsing HTML incrementally, as it streams in, which is part of why pages can start rendering before every byte has been downloaded.

Step 4: Building the DOM

As the browser parses the incoming HTML, it constructs the DOM (Document Object Model) — an in-memory, tree-shaped representation of the page's structure, which we cover in dedicated depth in What Is the DOM and Why Does It Matter? Each HTML element becomes a node in this tree, with parent-child relationships that mirror the nesting in the original markup.

Step 5: Fetching and Applying CSS — The CSSOM

Whenever the parser encounters a <link> tag referencing a stylesheet, the browser fetches that CSS file (or processes an inline <style> block directly) and builds a second tree structure called the CSSOM (CSS Object Model), representing every style rule that applies to the document. Critically, browsers generally will not render any content to the screen until they have both the DOM and the CSSOM ready, because rendering content without knowing its final styling would mean showing an unstyled flash of content and then immediately having to redraw everything — a jarring experience browsers deliberately avoid. This is one of the main reasons render-blocking CSS is such an important performance concept: until your stylesheet is fully downloaded and parsed, the browser is typically holding off on painting anything at all.

Step 6: Executing JavaScript

Depending on how a <script> tag is written, JavaScript can be fetched and executed at different points in this process — blocking the parser entirely while it downloads and runs (the default behavior), or deferred until parsing finishes, or loaded asynchronously without blocking parsing at all, using the async or defer attributes. JavaScript often modifies the DOM and CSSOM directly, which is why script placement and loading strategy have a real, measurable impact on how quickly a page appears usable to a visitor.

Worth remembering: a script placed in the <head> without async or defer will block the browser from continuing to parse the rest of the page until that script has fully downloaded and executed — a common, avoidable cause of slow-feeling pages.

Step 7: The Render Tree, Layout, and Paint

With the DOM and CSSOM both ready, the browser combines them into a render tree — essentially the DOM, but filtered down to only the elements that will actually be visible (excluding, for instance, elements with display: none), each annotated with its final computed styles. From there, the browser performs layout (sometimes called "reflow"): calculating the exact size and position of every visible element on the page, based on the viewport size, box model rules, and the styles from the CSSOM. Finally, the browser performs paint: actually drawing pixels — text, colors, borders, images, shadows — onto the screen, often across multiple layers that the browser can composite together efficiently, especially for elements that are animating or scrolling.

It Happens Again, Continuously

This entire process isn't a one-time event confined to the initial page load. Any time JavaScript modifies the DOM, any time CSS changes (through a hover state, an animation, or a class toggle), and any time the viewport is resized, the browser may need to redo some portion of this pipeline — recalculating styles, redoing layout, repainting — as efficiently as it can. Understanding which changes trigger the expensive parts of this pipeline (layout and paint) versus the cheaper parts (compositing) is central to writing performant, smooth-feeling web interfaces.

Key takeaways

See the rendering pipeline yourself

Edit HTML and CSS side by side and watch the live preview repaint instantly, right in your browser.

Open the Free Online Compiler →