A rendering engine, also known as a layout engine or web rendering core, is the subsystem inside the browser engine responsible for interpreting web documents (HTML, CSS, SVG, images) and drawing them onto the screen.
Understanding the rendering engine helps you optimize page performance, minimize reflows and repaints, and write CSS that renders efficiently.
Core Components of the Rendering Engine
HTML Parser
The HTML parser converts raw HTML text into a DOM Tree (Document Object Model). It handles incremental parsing, starting rendering before the entire HTML is downloaded, and fixes invalid markup automatically (browsers are forgiving).
<body>
<p>Hello <b>World</b></p>
</body>
Output: DOM Tree
Document
└─ html
├─ head
└─ body
└─ p
├─ #text "Hello "
└─ b
└─ #text "World"
CSS Parser
The CSS parser parses CSS rules (from style tags, linked stylesheets, and inline styles). It builds a CSSOM Tree (CSS Object Model) representing computed style information.
p { color: blue; font-size: 16px; }
Output: CSSOM Tree
CSSStyleSheet
└─ CSSRuleList
└─ CSSStyleRule
├─ selectorText: "p"
└─ style
├─ color: "blue"
└─ font-size: "16px"
Render Tree Construction
The DOM Tree (content) and CSSOM Tree (styles) are combined to produce the Render Tree. The render tree contains only visible elements, each with computed visual styles.
An element with display: none exists in DOM but not in the Render Tree.
Output: Render Tree, a hierarchical visual model of the page.
Layout / Reflow
The Render Tree is processed to determine the exact geometry of each element. Position (x, y), size (width, height), margins, padding, and borders are calculated based on the CSS box model and viewport constraints.
When there’s a change in content or styles (like window resize or content update), layout is recalculated (reflow).
Output: Each element gets coordinates, width, height, and other layout information needed for rendering.
Painting (Rasterization)
The browser translates the layout boxes into draw commands (colors, borders, text, images, etc.). For each node in the Layout Tree, a series of drawing instructions are generated for rendering. This is called painting or rasterization.
Output: A display list, a sequence of draw commands ready for actual rendering on the screen.
Example of draw commands:
Draw background color
Draw border
Draw text
Draw image
Layering and Compositing
For complex visual effects (like position: fixed, opacity, transform), the page is split into multiple layers. These layers are rasterized (converted to bitmaps) and often processed by the GPU for better performance.
The compositor thread merges these layers into the final image.
Output: A ready-to-display frame that is sent to the GPU and rendered on the screen.
Rendering Engine Data Flow
Here’s the high-level pipeline of what happens from code to pixels:
HTML + CSS + JS
↓
HTML Parser → DOM Tree
CSS Parser → CSSOM Tree
↓
Combine → Render Tree
↓
Layout (Reflow)
↓
Paint (Display List)
↓
Compositing (GPU)
↓
Screen (Display Frame)
Optimizations in Modern Rendering Engines
-
Incremental Rendering: Starts painting before the full page is loaded
-
Parallel Parsing: HTML, CSS, and scripts are parsed concurrently
-
GPU Acceleration: Offloads compositing and rasterization to the GPU
-
Lazy Layout & Paint: Only re-renders affected parts after DOM changes
-
Pre-rendering and Caching: Reuse layout and style data for speed
-
Display List & Skia (Blink): Efficient graphics library to batch paint commands
Rendering Engine Example Internals (Blink)
Blink, used by Chrome and Edge, has submodules like:
| Subsystem | Function |
|---|---|
| Document Loader | Receives data from the network module |
| HTMLTokenizer / HTMLTreeBuilder | Parses HTML incrementally |
| Style Engine | Parses CSS and computes styles |
| Layout Engine | Calculates positions and dimensions |
| Paint Controller | Records draw commands |
| Compositor / Raster Thread | Combines and renders final layers using GPU |
Performance Implications
Reflow (Layout)
Reflow is expensive because it requires recalculating positions and sizes for affected elements. It’s triggered by:
- Adding/removing DOM elements
- Changing element dimensions, margins, padding, borders
- Changing window size
- Reading certain properties like offsetHeight, scrollTop
Minimize reflows by:
- Batching DOM changes
- Using CSS transforms instead of changing position
- Avoiding layout-triggering property reads in loops
Repaint
Repaint is less expensive than reflow. It’s triggered by:
- Changing colors
- Changing visibility
- Changing background images
Minimize repaints by:
- Using CSS classes instead of inline styles
- Grouping style changes
- Using will-change CSS property for animations
Compositing
Compositing is the cheapest operation. It only affects GPU layers. Use CSS properties that only trigger compositing:
- transform
- opacity
- filter
Summary
| Stage | Description | Output |
|---|---|---|
| HTML Parsing | Convert HTML → DOM | DOM Tree |
| CSS Parsing | Convert CSS → CSSOM | CSSOM Tree |
| Style Calculation | Combine DOM + CSSOM | Render Tree |
| Layout | Compute geometry | Box dimensions |
| Paint | Draw visuals | Display list |
| Compositing | Merge layers | Frame on screen |
The rendering engine is the heart of how browsers display web content. Understanding its pipeline helps you write performant CSS and JavaScript that minimizes expensive operations like reflow and repaint.
By working with the rendering engine instead of against it, you can build fast, responsive web applications that provide excellent user experiences.