Building Your Learning Module...
Getting things ready for you!
Find videos you like?
Save to resource drawer for future reference!
The Critical Rendering Path (CRP) is the sequence of steps the browser goes through to convert HTML, CSS, and JavaScript into pixels on the screen. Understanding this process is key to optimizing page load performance.
Parse HTML → Build DOM tree
Parse CSS → Build CSSOM tree
Execute scripts (can block!)
Combine DOM + CSSOM
Calculate positions & sizes
Convert to pixels
Combine layers → Final image!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Critical Rendering Path Visualization</title>
</head>
<body>
<div class="container">
<h1>🔄 Critical Rendering Path Pipeline</h1>
<div class="pipeline">
<div class="stage">
<div class="stage-number">1</div>
<div class="stage-title">DOM Construction</div>
<div class="stage-description">
Browser parses HTML and builds the Document Object Model (DOM) tree.
Each HTML tag becomes a node in the tree.
</div>
<span class="stage-time">⏱️ ~50ms</span>
</div>
<div class="stage">
<div class="stage-number">2</div>
<div class="stage-title">CSSOM Construction</div>
<div class="stage-description">
Browser parses CSS and builds the CSS Object Model (CSSOM) tree.
This defines all the styles for elements.
</div>
<span class="stage-time">⏱️ ~100ms</span>
</div>
<div class="stage">
<div class="stage-number">3</div>
<div class="stage-title">JavaScript Execution</div>
<div class="stage-description">
If there are scripts (without async/defer), they block everything!
Scripts can modify both DOM and CSSOM.
</div>
<span class="stage-time">⏱️ ~200ms (or more!)</span>
</div>
<div class="stage">
<div class="stage-number">4</div>
<div class="stage-title">Render Tree Construction</div>
<div class="stage-description">
Browser combines DOM and CSSOM to create the Render Tree.
Only visible elements are included (no display:none).
</div>
<span class="stage-time">⏱️ ~30ms</span>
</div>
<div class="stage">
<div class="stage-number">5</div>
<div class="stage-title">Layout (Reflow)</div>
<div class="stage-description">
Browser calculates the exact position and size of each element.
This is where box model calculations happen.
</div>
<span class="stage-time">⏱️ ~40ms</span>
</div>
<div class="stage">
<div class="stage-number">6</div>
<div class="stage-title">Paint</div>
<div class="stage-description">
Browser converts the render tree into actual pixels on the screen.
Elements are painted in layers.
</div>
<span class="stage-time">⏱️ ~60ms</span>
</div>
<div class="stage">
<div class="stage-number">7</div>
<div class="stage-title">Composite</div>
<div class="stage-description">
Browser combines all layers into the final image.
User finally sees the page!
</div>
<span class="stage-time">⏱️ ~20ms</span>
</div>
</div>
<div class="optimization-tips">
<div class="tips-title">⚡ How to Optimize Each Stage:</div>
<ul class="tips-list">
<li><strong>DOM:</strong> Minimize HTML size, avoid deep nesting</li>
<li><strong>CSSOM:</strong> Inline critical CSS, defer non-critical styles</li>
<li><strong>JavaScript:</strong> Use async/defer, minimize blocking scripts</li>
<li><strong>Render Tree:</strong> Avoid complex selectors, minimize CSS rules</li>
<li><strong>Layout:</strong> Avoid layout thrashing, batch DOM reads/writes</li>
<li><strong>Paint:</strong> Reduce paint complexity, use CSS transforms</li>
<li><strong>Composite:</strong> Promote elements to layers wisely</li>
</ul>
</div>
</div>
</body>
</html>Loading preview...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Unoptimized Critical Rendering Path</title>
<!-- Render-blocking CSS -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap">
<link rel="stylesheet" href="large-styles.css">
<!-- Render-blocking JavaScript -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="large-app.js"></script>
</head>
<body>
<div class="container">
<h1>❌ Unoptimized Critical Rendering Path</h1>
<p style="margin-bottom: 20px; color: #4b5563;">
This page loads slowly because it has multiple render-blocking resources!
</p>
<div class="warning">
<div class="warning-title">⚠️ Problems with This Page:</div>
<ul class="problems">
<li>External font blocks rendering</li>
<li>Large CSS file blocks rendering</li>
<li>jQuery blocks rendering</li>
<li>Large JavaScript file blocks rendering</li>
<li>User sees blank page for 3-5 seconds!</li>
</ul>
</div>
<div class="loading-sim">
<div class="loading-text">⏳ Loading... (3-5 seconds)</div>
<p style="color: #78350f; margin-top: 10px; font-size: 0.9rem;">
Users are staring at a blank white screen!
</p>
</div>
</div>
</body>
</html>Loading preview...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Optimized Critical Rendering Path</title>
<!-- Preconnect to external domains -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Critical inline CSS for above-the-fold content -->
<!-- Preload critical font file -->
<link rel="preload" href="https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2" as="font" type="font/woff2" crossorigin>
<!-- Async load non-critical CSS -->
<link rel="preload" href="non-critical-styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<!-- Defer JavaScript -->
</head>
<body>
<div class="container">
<h1>✅ Optimized Critical Rendering Path</h1>
<p style="margin-bottom: 20px; color: #4b5563;">
This page loads instantly with optimized critical rendering!
</p>
<div class="success">
<div class="success-title">🚀 Optimizations Applied:</div>
<ul class="benefits">
<li>Critical CSS inlined in head</li>
<li>Fonts preloaded and preconnected</li>
<li>Non-critical CSS loaded async</li>
<li>JavaScript deferred</li>
<li>Page visible in under 1 second!</li>
</ul>
</div>
<div class="metrics">
<div class="metric-card">
<div class="metric-value">0.8s</div>
<div class="metric-label">Time to First Paint</div>
</div>
<div class="metric-card">
<div class="metric-value">1.2s</div>
<div class="metric-label">Largest Contentful Paint</div>
</div>
<div class="metric-card">
<div class="metric-value">0.1s</div>
<div class="metric-label">First Input Delay</div>
</div>
<div class="metric-card">
<div class="metric-value">0.05</div>
<div class="metric-label">Cumulative Layout Shift</div>
</div>
</div>
</div>
</body>
</html>Loading preview...
Reduce the number of resources needed before first render. Inline critical CSS, defer non-critical assets.
Compress and minify CSS/JS. Remove unused code. Optimize images. Every byte counts!
Reduce roundtrips. Use HTTP/2, CDNs, preconnect to third-party domains.
Load visible content first. Lazy load below-the-fold content. Users see something immediately.
All external CSS files block rendering by default
<link rel="stylesheet" href="styles.css"> ← Blocks!Scripts without async/defer block everything
<script src="app.js"></script> ← Blocks!Font files discovered late, cause FOUT/FOIT
@font-face in external CSS ← Delays rendering!Put above-the-fold CSS in a <style> tag in the head. Load the rest async.
Add defer to all scripts to prevent blocking. They'll execute after HTML parsing completes.
Use <link rel="preload"> for fonts and critical assets to load them early.
Use loading="lazy" for images and iframes that aren't immediately visible.
Use Chrome DevTools to measure:
Tools: Chrome DevTools Lighthouse, WebPageTest, PageSpeed Insights