Rendering Pipeline
The browser rendering pipeline transforms HTML/CSS into pixels on screen.
The Pipeline
1. DOM Construction
HTML → DOM Tree
2. CSSOM Construction
CSS → CSSOM Tree
3. Render Tree
DOM + CSSOM → Render Tree
(excludes hidden elements)
4. Layout
Calculate geometry (size, position)
5. Paint
Fill in pixels (colors, text, borders)
6. Composite
Combine layers into final image
JavaScript Blocking
// JavaScript blocks DOM construction
<script>
// This blocks parsing!
document.write('Hello'); // Even worse!
</script>
<!-- Use defer or async -->
<script defer src="app.js"></script>
<script async src="analytics.js"></script>
CSS Blocking
<!-- CSS blocks rendering until loaded -->
<link rel="stylesheet" href="styles.css">
<!-- Browser waits for CSS before rendering -->
<!-- Use media to make non-critical CSS non-blocking -->
<link rel="stylesheet" href="print.css" media="print">
<link rel="stylesheet" href="mobile.css" media="(max-width: 768px)">
Critical Rendering Path
1. HTML parsing starts
2. Encounters <link> → starts CSS download
3. Encounters <script> → blocks HTML parsing
4. Script executes → parsing resumes
5. DOM + CSSOM ready → Render tree built
6. Layout → Paint → Composite
Optimizing the Pipeline
// 1. Minimize DOM depth
// BAD
<div>
<div>
<div>
<div>
<span>Deep!</span>
</div>
</div>
</div>
</div>
// GOOD
<div class="container">
<span>Flat!</span>
</div>
// 2. Reduce DOM size
// BAD: 1000+ nodes
// GOOD: Virtual scrolling or pagination
// 3. Use efficient CSS selectors
/* BAD */
#header > div > ul > li > a { }
/* GOOD */
.nav-link { }
Render Tree
The render tree contains only visible elements with their computed styles.
What's in the Render Tree
// DOM tree includes everything
<div style="display: none">Hidden</div> // In DOM
<p>Visible</p> // In DOM
// Render tree excludes hidden
// <div> not included (display: none)
// <p> included with styles
Elements Not in Render Tree
<!-- Not in render tree: -->
<head>...</head> <!-- Document metadata -->
<script>...</script> <!-- Not visible -->
<div style="display: none"> <!-- Hidden -->
<div style="visibility: hidden"> <!-- Invisible but takes space -->
<meta> tags <!-- Not visible -->
Styles Affecting Render Tree
/* display: none - removes from render tree */
.hidden { display: none; }
/* visibility: hidden - in render tree but invisible */
.invisible { visibility: hidden; }
/* opacity: 0 - in render tree, invisible */
.transparent { opacity: 0; }
Layout vs Paint
// Layout: Calculate size and position
// - Triggered by: width, height, margin, padding, position
element.style.width = '100px'; // Triggers layout
element.style.position = 'absolute'; // Triggers layout
// Paint: Fill in pixels
// - Triggered by: color, background, shadow, text
element.style.color = 'red'; // Triggers paint only
element.style.boxShadow = '0 0 5px black'; // Triggers paint only
Layout and Paint
Layout calculates geometry, Paint fills in pixels. Both are expensive operations.
Layout
// Layout calculates:
// - Element dimensions (width, height)
// - Element position (top, left)
// - Margins, padding, borders
// What triggers layout:
element.offsetWidth; // Read
element.offsetHeight; // Read
element.getBoundingClientRect(); // Read
element.style.width = '100px'; // Write
window.getComputedStyle(); // Read
// Layout is synchronous and blocking!
Paint
// Paint fills in:
// - Background colors
// - Text rendering
n// - Borders
// - Shadows
// - Images
// What triggers paint:
element.style.color = 'red';
element.style.backgroundColor = 'blue';
element.style.boxShadow = '0 0 5px black';
// Paint can be expensive with:
// - Large areas
// - Complex shadows
// - Multiple layers
Composite
// Composite combines layers into final image
// Layers are created by:
// - 3D transforms
// - Video elements
// - Canvas elements
// - will-change property
// - z-index (in some cases)
// CSS to promote to layer:
.element {
will-change: transform;
/* or */
transform: translateZ(0);
}
// But don't overuse layers!
// Each layer consumes memory
Performance Optimization
// 1. Batch DOM reads and writes
const width = element.offsetWidth; // Read once
for (let i = 0; i < 100; i++) {
element.style.width = `${width + i}px`; // Write many
}
// 2. Use CSS for animations
// BAD
function animate() {
element.style.left = `${x}px`;
x++;
requestAnimationFrame(animate);
}
// GOOD
.element {
transition: left 0.1s;
}
.element.animate([
{ left: '0px' },
{ left: '100px' }
], { duration: 1000 });
// 3. Use transform instead of top/left
// BAD (triggers layout)
element.style.top = '100px';
element.style.left = '100px';
// GOOD (compositor only)
element.style.transform = 'translate(100px, 100px)';
Tools for Analysis
// Chrome DevTools Performance tab
// 1. Record performance
// 2. Look for layout/paint events
// 3. Check for long tasks
// Chrome DevTools Rendering tab
// - Paint flashing (green overlay)
// - Layout boundaries (borders)
// - Layer borders
// Lighthouse
// - Performance score
// - Core Web Vitals
Practice Problems
Create a reusable React component implementing Browser Rendering. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for Browser Rendering using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize Browser Rendering for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. What is the correct order of the rendering pipeline?
2. What triggers a layout reflow?
3. What is the difference between display: none and visibility: hidden?
4. Why is transform better than top/left for animations?
Flashcards
Question
What is the browser rendering pipeline?
Click to reveal answer
Answer
HTML → DOM → CSSOM → Render Tree → Layout → Paint → Composite → Pixels on screen.
Question
What triggers layout reflow?
Click to reveal answer
Answer
Changes to geometry: width, height, position, margins, padding, borders.
Question
display: none vs visibility: hidden?
Click to reveal answer
Answer
display: none removes from render tree. visibility: hidden keeps it but invisible (takes space).
Question
Why is transform faster than top/left?
Click to reveal answer
Answer
transform only triggers composite, not layout or paint. It's GPU-accelerated.
Question
What is Browser Rendering?
Click to reveal answer
Answer
Browser Rendering is a key concept in frontend development.
Revision Notes
Key Takeaways
- 1.The rendering pipeline: DOM → CSSOM → Render Tree → Layout → Paint → Composite
- 2.Layout is triggered by geometry changes, paint by visual changes
- 3.transform is faster than top/left because it skips layout
- 4.display: none removes from render tree, visibility: hidden keeps it
- 5.Batch DOM operations to minimize reflows
Interview Tips
- •Walk through the rendering pipeline step by step
- •Explain what triggers layout vs paint
- •Discuss why transform is better for animations
- •Show how to minimize reflows in code
Cheat Sheet
Browser Rendering Cheat Sheet
Pipeline Steps
- DOM Construction (HTML → DOM)
- CSSOM Construction (CSS → CSSOM)
- Render Tree (DOM + CSSOM)
- Layout (geometry calculation)
- Paint (pixel filling)
- Composite (layer combining)
What Triggers Layout
- width, height, position
- margins, padding, borders
- offsetWidth, offsetHeight
What Triggers Paint
- color, background
- shadows, borders
- text, images
Optimization
- Batch reads/writes
- Use transform for animations
- Use CSS classes for styling
- Minimize DOM depth