Browser Rendering Explained: From HTML to Pixels
Know the path from bytes to pixels, and you know where to look when a page feels slow.
The browser has a pipeline, not a single render step
A browser does not receive HTML and immediately paint it. It parses the document into a DOM, parses CSS into a CSSOM, combines those trees into a render tree, calculates layout, paints pixels and then composites layers. JavaScript can interrupt that pipeline at almost any stage.
1. HTML becomes the DOM
The HTML parser builds a tree as bytes arrive. A normal <script> without defer can pause parsing while the browser downloads and executes JavaScript. For a content site, that is an easy way to make first render depend on code the visitor did not need yet.
2. CSS builds the CSSOM
CSS is render-blocking because the browser needs style information before it can safely paint the page. Keep the critical stylesheet small, avoid unnecessary @imports, and load non-critical CSS later. The goal is not “zero CSS”; it is “only the CSS needed for the first viewport blocks first paint.”
3. Layout, paint and composite are different costs
Layout calculates geometry. Paint turns boxes, text and images into drawing commands. Composite assembles layers on the GPU. A property such as transform can often be composited cheaply, while repeatedly changing width or top can trigger layout and paint work.
4. JavaScript is the wildcard
Even a small script can become expensive if it reads layout immediately after changing styles, creating a forced synchronous layout. Batch DOM writes, then reads, and prefer event-driven work over constant polling. Long tasks over 50ms are especially damaging to interaction responsiveness.
A practical debugging order
- Measure LCP, INP and CLS.
- Identify the largest render-blocking resources.
- Find long JavaScript tasks in the Performance panel.
- Check for layout thrashing and oversized images.
- Move non-critical work after first interaction.
The fastest page is usually not the page with the most clever CSS. It is the page that asks the browser to do less work before the user can read and interact with it.