Skip to content

Rendering Engine: Deep Dive

The rendering engine is the core component of a web browser responsible for parsing, laying out, and painting web content (HTML, CSS, JavaScript). It transforms raw code into pixels on the screen.


EngineBrowsersMaintainer
BlinkChrome, Edge, OperaGoogle
GeckoFirefoxMozilla
WebKitSafariApple

  • HTML Parsing:
    • Converts HTML into a DOM (Document Object Model) tree.
    • Handles malformed HTML via error recovery (e.g., auto-closing tags).
  • CSS Parsing:
    • Converts CSS into a CSSOM (CSS Object Model) tree.
    • Resolves cascading and specificity rules.
  • JavaScript Parsing:
    • Can block HTML/CSS parsing (unless marked async/defer).
    • Uses the JavaScript engine (e.g., V8, SpiderMonkey) to execute code.
  • Combines DOM and CSSOM into a Render Tree:
    • Only visible nodes (e.g., excludes display: none).
    • Computes final styles for each node (inheritance, media queries).
  • Purpose: Calculates the exact position/size of each element.
  • Process:
    1. Box Model: Computes margins, borders, padding, and content dimensions.
    2. Coordinate System: Places elements relative to viewport/parents.
    3. Flows: Handles block/inline/flex/grid layouts.
  • Optimizations:
    • Dirty bit system: Only re-layouts affected elements.
    • Incremental layout for dynamic content.
  • Purpose: Converts layout into pixels.
  • Steps:
    1. Paint Layers: Splits the render tree into layers (e.g., for compositing).
    2. Rasterization: Converts vectors (e.g., text, SVG) to pixels.
    3. GPU Acceleration: Offloads complex tasks (e.g., transforms, opacity) to GPU.
  • Techniques:
    • Double Buffering: Renders to an offscreen buffer to avoid flickering.
    • Partial Repaints: Only redraws damaged regions.
  • Purpose: Merges layers efficiently for final display.
  • Key Concepts:
    • Layers: Independent paint layers (e.g., will-change, transform).
    • Compositor Thread: Offloads layer merging to a separate thread for smooth scrolling/animations.
  • Output: A single bitmap sent to the screen.

  • Critical Rendering Path (CRP):
    • Minimizes steps from HTML → pixels (e.g., inline critical CSS).
  • Jank-Free Rendering:
    • Targets 60 FPS by limiting main thread work (e.g., using requestAnimationFrame).
  • Layer Squashing: Combines overlapping layers to reduce memory.
  • Garbage Collection: Cleans up unused DOM nodes/styles.
  • Multithreading:
    • Blink/WebKit use separate threads for parsing, layout, and compositing.
  • Off-Main-Thread Work:
    • Non-UI tasks (e.g., image decoding) run on worker threads.

  • Edge Cases:
    • Flexbox/grid alignment, z-index stacking contexts.
  • Performance Bottlenecks:
    • Nested layouts trigger “layout thrashing” (forced synchronous reflows).
  • DOM Mutations:
    • Frequent updates (e.g., animations) require efficient diffing.
  • JavaScript Blocking:
    • Long-running scripts delay rendering (mitigated via requestIdleCallback).
  • Font Rendering: Differences in anti-aliasing (e.g., macOS vs. Windows).
  • GPU Variations: Driver bugs affect hardware acceleration.

  • Chrome DevTools:
    • Layers Panel: Visualize compositing layers.
    • Performance Tab: Profile reflows/paints.
  • Firefox Renderer:
    • Paint Flashing: Highlights repainted areas.

  • WebGPU: Next-gen GPU API for faster rendering.
  • Houdini: Low-level CSS/JS APIs for custom rendering logic.
  • Partial Trees: Isolated rendering for components (e.g., React Server Components).

Runtime vs. Rendering Engine: Key Differences

Section titled “Runtime vs. Rendering Engine: Key Differences”
FeatureRuntimeRendering Engine
Primary RoleExecutes code/manages stateDisplays visual content
What It Handles- Memory allocation
- Garbage collection
- Event loop
- API calls (e.g., fetch, setTimeout)
- Parsing HTML/CSS
- Layout calculations
- Painting pixels
- Compositing layers
Examples- JavaScript V8 engine (Chrome)
- Python interpreter
- JVM (Java)
- Blink (Chrome)
- Gecko (Firefox)
- WebKit (Safari)
Performance Focus- Optimizing code execution
- Reducing CPU/memory overhead
- Minimizing repaints
- Accelerating GPU rendering
InputScripts (e.g., JS, bytecode)Markup/styles (e.g., HTML/CSS)
OutputProgram results (e.g., state changes)Pixels on screen
Key Challenges- JIT compilation
- Garbage collection pauses
- Layout thrashing
- Style recalculation

  1. Purpose:

    • Manages program execution (e.g., running JavaScript, handling callbacks).
    • Provides APIs for I/O, networking, and system interactions.
  2. Components:

    • Call Stack: Tracks function execution.
    • Heap: Manages memory allocation.
    • Event Loop: Handles async operations (e.g., promises).
  3. Example Workflow:

    console.log("Hello"); // Runtime parses and executes this line.
  1. Purpose:

    • Converts structured content (HTML/CSS) into visual output.
    • Ensures pixels are updated efficiently.
  2. Pipeline:

    • Parsing: HTML → DOM, CSS → CSSOM.
    • Layout: Calculates element positions (reflow).
    • Paint: Fills pixels (repaint).
    • Composite: Layers elements for GPU acceleration.
  3. Example Workflow:

    <div style="color: red;">Hello</div>
    <!-- Rendering engine paints this. -->

  1. Browser Context:

    • The runtime (e.g., V8) executes JavaScript, which may modify the DOM.
    • The rendering engine (e.g., Blink) updates the screen when the DOM changes.
  2. Performance Tradeoffs:

    • A slow runtime (e.g., excessive GC) → Delayed JS execution → Jank.
    • A slow rendering engine → Laggy visuals (e.g., slow scrolling).

  • Runtime = A play’s script + director (orchestrates actions).
  • Rendering Engine = The stage + lighting crew (makes it visible).