
Browser Rendering: What happens when you type a URL?
From HTML parsing to DOM, CSSOM, Render Tree, Layout, Paint, and Composite. Mastering the Critical Rendering Path (CRP), Preload Scanner, Reflow vs Repaint, and requestAnimationFrame.

From HTML parsing to DOM, CSSOM, Render Tree, Layout, Paint, and Composite. Mastering the Critical Rendering Path (CRP), Preload Scanner, Reflow vs Repaint, and requestAnimationFrame.
A comprehensive deep dive into client-side storage. From Cookies to IndexedDB and the Cache API. We explore security best practices for JWT storage (XSS vs CSRF), performance implications of synchronous APIs, and how to build offline-first applications using Service Workers.

Establishing TCP connection is expensive. Reuse it for multiple requests.

Tired of naming classes? Writing CSS directly inside HTML sounds ugly, but it became the world standard. Why?

HTTP is Walkie-Talkie (Over). WebSocket is Phone (Hello). The secret tech behind Chat and Stock Charts.

Have you ever wondered what happens between hitting "Enter" in the address bar and seeing the website appear? It feels instantaneous, but inside the browser, a complex pipeline of operations is executing. This pipeline is called the Critical Rendering Path (CRP).
Understanding CRP is not just for browser engineers. It is the single most important knowledge for Frontend Developers who want to optimize performance. Knowing why an animation stutters (Jank) or why a page loads slowly often comes down to understanding how the browser paints pixels.
Let's dissect the 5 stages of rendering: Parsing, Render Tree, Layout, Paint, and Composite.
When the server sends index.html, it's just a stream of 0s and 1s (Bytes).
The browser engine (Blink, WebKit, Gecko) converts them:
<, d, i, v, >)StartTag: div)div element object)body -> div -> span)While the main HTML parser buids the DOM tree, it gets blocked by synchronous scripts (<script src="...">).
To prevent wasting time, modern browsers use a Preload Scanner.
This background process peeks ahead in the HTML stream to find resources like images, stylesheets, and scripts and starts downloading them immediately.
This parallelization is why putting vital resources early in the HTML helps performance.
While parsing HTML, if the browser sees <link rel="stylesheet">, it pauses to fetch the CSS.
Just like DOM, CSS is parsed into a tree structure called CSSOM.
It handles the "Cascading" logic. If div inherits color from body, the CSSOM calculates that final computed style.
The browser cannot render anything until both DOM and CSSOM are ready. This is why CSS is called a "Render Blocking Resource".
Now we have DOM (Content) and CSSOM (Style). We combine them to create the Render Tree. The Render Tree contains only what is visible on the screen.
display: none vs visibility: hiddenThis distinction is crucial for understanding the Render Tree.
display: none: The element is removed from the Render Tree. It does not exist for the renderer. Zero rendering cost.visibility: hidden: The element is in the Render Tree. It is invisible, but it still takes up empty space (layout calculation needed).opacity: 0: Also in the Render Tree.Using display: none triggers a reconstruction of the Render Tree, while opacity updates usually happen at the Paint or Composite stage.
The browser now knows what to draw, but not where. Layout is the process where the browser calculates the precise position and size of each node in Pixels.
They are often confused but are very different.
| Trigger | Layout (Reflow) | Paint (Repaint) | Composite Only |
|---|---|---|---|
| Properties | width, height, left | color, background | transform, opacity |
| Cost | Expensive (CPU) | Moderate (CPU/GPU) | Cheap (GPU) |
| Scope | Whole Document (often) | Element Only | Texture Only |
Reflow is the most expensive operation. It triggers a chain reaction. If you change the width of a <body>, it ripples down to every single child element.
Running JavaScript that reads layout properties can force the browser to perform a synchronous Reflow.
// Bad Code: Layout Thrashing
const list = document.getElementById('list');
for (let i = 0; i < 100; i++) {
// Reading offsetWidth forces the browser to calculate layout immediately
const width = list.offsetWidth;
list.style.width = (width + 10) + 'px'; // Writing style invalidates layout
}
This "Read-Write-Read-Write" pattern forces the browser to re-calculate layout 100 times.
Fix: Read the value once outside the loop, or use requestAnimationFrame.
Now the browser has the geometry. It's time to fill the pixels. Paint involves drawing text, colors, images, borders, and shadows. The browser doesn't confirm everything to one bitmap. It creates multiple Layers.
For example, video elements, canvas, or elements with certain CSS properties (will-change, 3D transform, position: fixed) are promoted to their own layers.
This allows the browser to repaint only that specific layer when it changes, instead of repainting the whole page.
This is the final step. All the painted layers are sent to the GPU (Graphics Processing Unit). The GPU flattens these layers into one final image that you see on the screen. This is Composite.
Operations handled by the GPU (Composite) are extremely fast and power-efficient. Operations handled by the CPU (Layout, Paint) are slow.
The Golden Rule of Animation: Prefer modifying properties that only trigger Composite, and avoid properties that trigger Layout.
width, height, top, left, margin. (Triggers Layout -> Paint -> Composite). The CPU has to recalculate the geometry of the element AND its neighbors.transform, opacity. (Triggers only Composite). The GPU just moves the texture.Next time you move a sidebar, use transform: translateX(100px) instead of left: 100px. The visual result is the same, but the performance difference is night and day.
For smooth animations, always use requestAnimationFrame(callback) instead of setTimeout.
setTimeout(fn, 16): "Try to run this after 16ms." If the main thread is busy, it will be delayed. It is not synced with the display refresh rate.requestAnimationFrame(fn): "Run this right before the next repaint." The browser optimizes this to run exactly at the monitor's refresh rate (e.g., 60Hz or 144Hz). It guarantees the smoothest possible animation loop.Modern frameworks like React often use CSS-in-JS libraries (Generic styled-components, Emotion).
While convenient (scoped styles, dynamic props), they come with a Runtime Cost.
<style> tag into the DOM.Compared to standard .css files or utility-first frameworks like Tailwind CSS, CSS-in-JS solutions can delay the Time to Interactive (TTI), especially on mobile devices with slower CPUs.
This is why the industry is shifting towards Zero-runtime CSS solutions (like Vanilla Extract or Tailwind) for critical applications.
To make your website fast, you need to help the browser process these steps quickly:
requestAnimationFrame.will-change: transform for moving elements to hint the browser to use GPU.Understanding underlying engine mechanics distinguishes a "Coder" from an "Engineer". When you see a stuttering webpage, don't just blame the network. Look at the Rendering Path.