Skip to main content

Overview

The critical rendering path is the sequence of steps the browser takes to convert HTML, CSS, and JavaScript into a rendered page. Optimizing this path is crucial for fast initial page loads and excellent user experience.
The critical rendering path directly impacts First Contentful Paint (FCP) and Largest Contentful Paint (LCP), two key Core Web Vitals metrics.

Understanding the rendering path

The browser follows these steps to render a page:
1

Parse HTML

The browser parses HTML to construct the DOM (Document Object Model) tree.
2

Parse CSS

CSS files are parsed to construct the CSSOM (CSS Object Model) tree.
3

Execute JavaScript

JavaScript can modify both DOM and CSSOM, potentially blocking rendering.
4

Construct render tree

DOM and CSSOM are combined to create the render tree (only visible elements).
5

Layout

Calculate exact position and size of each element.
6

Paint

Draw pixels to the screen.
CSS is render-blocking by default. JavaScript is both parser-blocking and render-blocking. These are the primary optimization targets.

Eliminate render-blocking resources

Render-blocking resources prevent the browser from displaying content until they’re downloaded and processed.

Identifying render-blocking resources

Run a Lighthouse audit and check the “Eliminate render-blocking resources” opportunity.
Look for:
  • Stylesheets in <head>
  • Synchronous <script> tags
  • Large CSS files
  • Unused CSS rules

Async and defer scripts

Use async for scripts that:
  • Don’t depend on other scripts
  • Don’t modify the DOM before it’s ready
  • Can execute in any order
Examples: Analytics, ads, social media widgets
Use defer for scripts that:
  • Need the full DOM to be parsed
  • Depend on other scripts (execution order matters)
  • Can wait until HTML parsing completes
Examples: Main application code, UI libraries, DOM manipulation
Use blocking scripts (no async/defer) only when:
  • Script must execute before page renders
  • Other scripts depend on it immediately
Examples: Critical polyfills, A/B testing that prevents FOUC

Minimize critical CSS

Critical CSS is the minimum CSS needed to render above-the-fold content.

Extracting critical CSS

1

Identify critical styles

Determine which CSS rules are needed for above-the-fold content.
2

Inline critical CSS

Place critical CSS directly in the <head> to eliminate the network request.
3

Defer non-critical CSS

Load remaining CSS asynchronously to avoid blocking rendering.

Implementation approaches

Async CSS loading pattern

Use media queries to load CSS conditionally:
Browsers still download all stylesheets but only block rendering for matching media queries.

Defer non-critical JavaScript

Defer JavaScript that’s not essential for initial rendering to improve page load performance.

Lazy loading JavaScript

Third-party script optimization

Download and serve third-party scripts from your own domain to improve caching and reduce DNS lookups.
Benefits:
  • Control over caching headers
  • No third-party DNS lookup
  • Better privacy
  • Reduced connection overhead
Replace heavy third-party embeds with lightweight facades that load the real thing on interaction.
Saves ~500KB by loading YouTube player only on click.
Load analytics, social widgets, and ads after critical content.
Third-party scripts can significantly impact performance. Audit them regularly and remove unused ones.

Preload, prefetch, and preconnect strategies

Resource hints tell the browser to optimize loading for specific resources.

Resource hint types

Preload

Load critical resources early in the page lifecycle.Priority: High
Use for: Critical fonts, CSS, scripts, images

Prefetch

Load resources needed for future navigation during idle time.Priority: Low
Use for: Next page resources, likely user actions

Preconnect

Establish early connections to important third-party origins.Priority: Medium
Use for: API domains, CDNs, fonts

DNS-prefetch

Resolve DNS early for third-party domains.Priority: Low
Use for: Multiple third-party domains

Preload examples

Always include crossorigin attribute for font preloads, even for same-origin fonts.

Prefetch examples

Prefetch resources during idle time:

Preconnect examples

Resource hint decision tree

1

Is it critical for initial render?

Yes → Use preloadNo → Go to step 2
2

Will the user likely need it soon?

Yes → Use prefetchNo → Go to step 3
3

Does it require a third-party connection?

Yes → Use preconnect or dns-prefetchNo → Don’t use resource hints
Don’t overuse resource hints. Too many preloads can delay actual critical resources. Limit to 3-5 preloads per page.

Complete optimization example

Measuring impact

Critical rendering path checklist

  • Minimize HTML size
  • Enable compression (gzip/brotli)
  • Use early hints (103 status code)
  • Optimize server response time (TTFB < 200ms)
  • Extract and inline critical CSS
  • Async load non-critical CSS
  • Remove unused CSS
  • Minimize CSS file size
  • Use media queries for conditional loading
  • Defer non-critical scripts
  • Use async for independent scripts
  • Minimize JavaScript execution time
  • Code split and lazy load
  • Optimize third-party scripts
  • Preload critical resources
  • Preconnect to required origins
  • Prefetch likely next resources
  • Optimize font loading
  • Lazy load below-fold images
  • Lighthouse score > 90
  • FCP < 1.8s
  • LCP < 2.5s
  • TTI < 3.8s
  • Monitor real user metrics (RUM)

Next steps

Profiling tools

Use Chrome DevTools and Lighthouse to identify optimization opportunities

Optimization techniques

Apply memoization, virtualization, and code splitting for better performance