Skip to content

The Rendering Pipeline

The browser’s rendering pipeline converts HTML, CSS, and JavaScript into pixels on the screen. Understanding each stage helps you write performant code.

flowchart LR
A["JavaScript\n(DOM/CSS changes)"] --> B["Style\nCalculation"]
B --> C["Layout\n(Reflow)"]
C --> D["Paint\n(Repaint)"]
D --> E["Compositing"]

The browser computes which CSS rules apply to each element and calculates their final styles.

// Accessing computed styles
const style = getComputedStyle(element);
console.log(style.color); // 'rgb(255, 0, 0)'
// Changing a class triggers style recalculation
element.classList.add('highlight');

The browser calculates the position and size of each element. This is the most expensive stage.

// Reading layout properties forces a synchronous layout
const width = element.offsetWidth; // Forces layout
const height = element.offsetHeight; // Uses cached layout
// Batch reads together
const rect = element.getBoundingClientRect();
// Then batch writes
element.style.width = '100px';
element.style.height = '200px';

The browser fills in pixels — colors, backgrounds, borders, text.

// Changes that only trigger paint (no layout)
element.style.color = 'red';
element.style.backgroundColor = '#f0f0f0';
element.style.boxShadow = '2px 2px 4px black';

The browser layers painted elements and composites them on the GPU.

// Changes that only trigger compositing (fastest!)
element.style.transform = 'translateX(100px)';
element.style.opacity = '0.5';
StageTriggersCost
StyleClass changes, inline stylesLow
LayoutWidth, height, position, fontHigh
PaintColor, background, shadowMedium
CompositingTransform, opacityLow 🚀
  • The pipeline runs in order: Style → Layout → Paint → Composite
  • Layout (reflow) is the most expensive stage
  • Compositing-only changes (transform, opacity) are cheapest
  • Batch read/write operations to avoid forced layouts