Injecting Critical CSS
Generating and Injecting Critical CSS¶
Critical CSS is the minimal set of styles required to render the above-the-fold content of a webpage. By extracting and injecting this CSS early, you reduce render-blocking delays and improve Largest Contentful Paint (LCP) and First Contentful Paint (FCP). This section explains how to generate and inject critical CSS using tools like PurgeCSS and the purgecss-plugin-critical plugin.
1. Identify the Critical Rendering Path¶
Before generating critical CSS, identify the elements that make up the above-the-fold content. Use tools like Lighthouse or Chrome DevTools to analyze the critical rendering path. For dynamic content, manually inspect the DOM to ensure all visible elements are included.
Example:
If your homepage has a hero section with a heading, image, and button, these elements define the critical rendering path.
2. Generate Critical CSS with PurgeCSS¶
PurgeCSS is a tool that removes unused CSS from your project. The purgecss-plugin-critical plugin extends this to extract critical CSS by analyzing the DOM.
Step-by-Step Setup¶
-
Install dependencies:
-
Configure PurgeCSS: Create a
purgecss.config.jsfile to define your project's CSS files and purge rules: -
Run PurgeCSS:
This generates acritical.cssfile containing only the styles needed for the specified elements.
3. Inject Critical CSS into HTML¶
Inject the generated critical.css into the <head> of your HTML to ensure it loads before other CSS. Use a script to dynamically add the <style> tag.
Example: Dynamic Injection¶
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Site</title>
<style id="critical-styles"></style>
</head>
<body>
<!-- Your page content -->
<script>
const criticalCSS = document.createTextNode(`
/* Paste your critical.css content here */
#hero { color: #fff; }
.logo { font-size: 24px; }
.cta-button { background: #007bff; }
`);
document.getElementById('critical-styles').appendChild(criticalCSS);
</script>
</body>
</html>
Alternative: Build-Time Injection¶
In frameworks like Next.js, use next.config.js to inject critical CSS during the build process:
module.exports = {
webpack(config, { isServer }) {
if (!isServer) {
config.entry('main').prepend('./src/critical.css');
}
return config;
},
};
4. Load Non-Critical CSS Asynchronously¶
After injecting critical CSS, load the rest of your styles asynchronously to avoid blocking rendering. Use <link rel="preload"> or @media queries to defer non-critical styles.
Example:
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
5. Validate with Lighthouse¶
Use Lighthouse to audit your page and ensure critical CSS is optimized: 1. Open Chrome DevTools → Audits → Run audit. 2. Check the Performance score and verify that critical CSS is below 15KB (recommended).
Key takeaways¶
- Generate critical CSS using PurgeCSS with the
purgecss-plugin-criticalplugin to isolate styles for above-the-fold content. - Inject critical CSS into the
<head>dynamically or during the build process to ensure it loads first. - Load non-critical CSS asynchronously to avoid render-blocking and improve LCP/FCP.
- Validate results with Lighthouse to ensure critical CSS is minimal and effective.