# Sujeet Jaiswal - Technical Blog (Full Content) > Complete technical blog content for LLM consumption. Source: https://sujeet.pro Generated: 2026-04-21T21:25:44.934Z Total content: 188 (185 articles, 0 blogs, 3 projects) --- # BROWSER & RUNTIME INTERNALS Deep dives into browser rendering and JavaScript runtime internals. --- ## Critical Rendering Path: Rendering Pipeline Overview **URL:** https://sujeet.pro/legacy-personal-site/v4/articles/browser-runtime-internals/critical-rendering-path/crp-rendering-pipeline-overview **Category:** Browser & Runtime Internals / Critical Rendering Path **Description:** The browser’s rendering pipeline transforms HTML, CSS, and JavaScript into visual pixels through a series of discrete, highly optimized stages. Modern browser engines like Chromium employ the RenderingNG architecture—a next-generation rendering system developed between 2014 and 2021—which decouples the main thread from the compositor and GPU processes to ensure 60fps+ performance and minimize interaction latency. # Critical Rendering Path: Rendering Pipeline Overview The browser's rendering pipeline transforms HTML, CSS, and JavaScript into visual pixels through a series of discrete, highly optimized stages. Modern browser engines like Chromium employ the **RenderingNG** architecture—a next-generation rendering system developed between 2014 and 2021—which decouples the main thread from the compositor and GPU processes to ensure 60fps+ performance and minimize interaction latency.
![The RenderingNG pipeline: Main thread stages (DOM → Paint) produce immutable outputs committed to the compositor thread, which handles rasterization and compositing independently.](./the-renderingng-pipeline-main-thread-stages-dom-paint-produce-immutable-outputs-.svg)
The RenderingNG pipeline: Main thread stages (DOM → Paint) produce immutable outputs committed to the compositor thread, which handles rasterization and compositing independently.
## Abstract The rendering pipeline is fundamentally a **producer-consumer architecture** split across threads and processes: - **Main Thread**: Produces structured data (DOM, CSSOM, computed styles, layout geometry, property trees, display lists). Each stage's output is immutable once complete. - **Compositor Thread**: Consumes committed data to handle scrolling, animations (transform/opacity), and frame assembly without blocking the main thread. - **Viz Process**: Aggregates compositor frames from all sources and issues GPU draw calls. The key insight: **Property Trees** (transform, clip, effect, scroll) replaced monolithic layer trees, reducing animation updates from O(layers) to O(affected nodes). This enables compositor-driven animations that bypass the main thread entirely—the architectural foundation for responsive scrolling and 60fps animations even when JavaScript is busy. Performance impact flows from this split: Interaction to Next Paint (INP) measures how quickly the pipeline can present a frame after user input. Each pipeline stage that runs on the main thread directly contributes to input delay and processing time. ## Pipeline Stages: Inputs and Outputs Each stage has well-defined inputs and outputs. Understanding this data flow is essential for debugging performance issues. | Stage | Input | Output | Consumed By | | ------------------------------------------------------------- | ---------------------------------- | -------------------------------------------------------------------------- | ---------------- | | [**DOM Construction**](../crp-dom-construction/README.md) | HTML bytes | DOM Tree | Style Recalc | | [**CSSOM Construction**](../crp-cssom-construction/README.md) | CSS bytes | CSSOM Tree | Style Recalc | | [**Style Recalc**](../crp-style-recalculation/README.md) | DOM + CSSOM | ComputedStyle (per node) + **LayoutObject Tree** | Layout | | [**Layout**](../crp-layout/README.md) | LayoutObject Tree + ComputedStyle | **Fragment Tree** (immutable geometry) | Prepaint | | [**Prepaint**](../crp-prepaint/README.md) | LayoutObject Tree + Fragment Tree | **Property Trees** (transform, clip, effect, scroll) + paint invalidations | Paint | | [**Paint**](../crp-paint/README.md) | LayoutObject Tree + Property Trees | **Display Lists** (drawing commands) | Commit | | [**Commit**](../crp-commit/README.md) | Property Trees + Display Lists | Copied data on compositor thread | Layerize, Raster | | **Layerize** | Display Lists | Composited layer list | Raster | | [**Raster**](../crp-raster/README.md) | Display Lists + Tiles | GPU texture tiles (bitmaps) | Composite | | [**Composite**](../crp-composit/README.md) | Texture tiles + Property Trees | Compositor Frame (DrawQuads) | Draw | | [**Draw**](../crp-draw/README.md) | Compositor Frame | Pixels on screen | Display | **Key distinction**: The **LayoutObject Tree** is created during Style Recalc, not Layout. Layout _annotates_ the LayoutObject tree and produces the immutable **Fragment Tree** as its output. Prepaint then traverses the LayoutObject tree (using Fragment Tree data) to build Property Trees. ## The Critical Rendering Path (CRP) The **Critical Rendering Path (CRP)** is the sequence of steps the browser undergoes to convert code into a visual frame. While traditionally viewed as a linear flow (DOM → CSSOM → Render Tree → Layout → Paint), modern engines employ a granular multi-threaded architecture designed around a core constraint: the main thread handles both JavaScript execution and rendering pipeline stages, so any work on the main thread delays both script responsiveness and visual updates. ### Design Rationale: Why Multi-Threading Matters > **Prior to RenderingNG (pre-2021)**: Rendering was deeply coupled. Scrolling could trigger expensive style recalculations. Animation of transforms required full layer tree walks. The single-threaded assumption baked into the original WebKit codebase (dating to 1998) meant rendering work blocked JavaScript and vice versa. RenderingNG's design addresses this by: 1. **Separating concerns**: Each pipeline stage produces well-defined, immutable outputs 2. **Enabling skip logic**: Stages that aren't needed can be bypassed (e.g., transform animations skip layout and paint) 3. **Offloading work**: Compositor-driven operations don't require main thread involvement ## The RenderingNG Pipeline Stages The pipeline comprises 12 stages, though several can be skipped when unnecessary. The first six run on the main thread; the remainder run on the compositor thread and Viz process. ### DOM Construction The browser parses HTML bytes into the Document Object Model (DOM) tree. This process is incremental—the browser starts building the tree before the entire document downloads. **Blocking Behavior**: - **JS is Parser Blocking**: Synchronous `` detection in strings | | **Character references** | Entity decoding | `&` → `&` | The tokenizer emits five token types: DOCTYPE, start tag, end tag, comment, and character tokens. Each token triggers tree construction actions. ### Stage 2: Tree Construction Tree construction uses **insertion modes** to determine how tokens modify the DOM. The specification defines 23 insertion modes including: - `initial`, `before html`, `before head`, `in head`, `after head` - `in body` (handles most content) - `in table`, `in row`, `in cell` (table-specific rules) - `in template` (for `