When you’re chasing a perfect Core Web Vitals score, CSS is often the biggest bottleneck. By default, browsers treat stylesheets as render‑blocking resources: the browser must download your CSS and build the CSSOM before it can paint anything that depends on those styles.
That’s where Critical CSS comes in.
Instead of inlining every used rule or forcing visitors to wait for a large stylesheet, you inline only the CSS required to render above‑the‑fold content and defer everything else. This keeps your initial HTML small enough to transfer quickly, reduces render‑blocking, and helps key metrics like First Contentful Paint (FCP) and Largest Contentful Paint (LCP).
For a full walkthrough on improving Core Web Vitals in WordPress, see my Core Web Vitals optimisation case study.
Inlining all used CSS might feel like a quick win, but it’s usually a trap: embedding the entire stylesheet in your HTML bloats the document, slows down Time to First Byte (TTFB), and eliminates the benefits of browser caching across pages. 1
In this guide, you’ll learn how the critical rendering path works, why CSS is render‑blocking and how to fix it, and how to generate and inline Critical CSS the right way—so you can speed up real‑world loading experiences without sacrificing maintainability or cache efficiency.
What is the Critical Rendering Path?
Understanding Render-Blocking Resources
When someone visits your website, the browser first constructs two key structures:
- The Document Object Model (DOM)
- The CSS Object Model (CSSOM)
These combine to form the render tree, which tells the browser what to display and how to style it. If a large stylesheet file is referenced early in the <head> tag, the browser has to pause and wait until that file is downloaded and parsed before it can render any content that depends on those styles. This is why CSS is considered a render‑blocking resource. 2
Critical CSS vs. Inlining All Used CSS
Critical CSS
- The minimum CSS required to render the above-the-fold (initial viewport) content.
- Focused only on what’s needed for the first paint.
Used CSS
- All CSS rules that are actually used on a page (during or after load), excluding unused rules.
- Can cover both above-the-fold and below-the-fold content.
The Caching Dilemma: Why External Files Matter
External stylesheet files are cached by the browser. When users navigate between pages, they don’t need to re‑download these files as long as the cache is still valid.
If you inline all used CSS:
- No effective stylesheet caching across pages: The visitor has to download the same CSS code again on every page view, because it’s embedded in each HTML document rather than in a shared external file.
- Bandwidth waste: A user visiting 10 pages must repeatedly download the bulk of your styles. In practice, this often costs significantly more bandwidth than inlining only a small critical subset and caching the rest.
The Critical CSS benefit:
You inline only a relatively small critical snippet (often on the order of a few to low‑tens of kilobytes, when minified). The rest of your CSS stays in an external file, which the browser can cache and reuse. This pattern:
- Speeds up the initial render on first view.
- Preserves cache efficiency for subsequent views and other pages.
So, when is it OK to inline the full CSS? That approach can be reasonable for very small, single‑page or landing‑page sites with concise stylesheets and minimal need for cross‑page caching, where the total HTML + CSS payload still comfortably stays within a single initial TCP congestion window.
HTML Bloat and the ~14 KB TCP Threshold
Inlining large amounts of CSS directly into the HTML significantly increases the document size. Larger files take longer to transmit, delay rendering, and harm performance—especially for users on mobile networks or with limited bandwidth.
Two effects to keep in mind:
- Slower TTFB (perceived): The server and network must move more bytes before the browser has enough of the document to start parsing and painting useful content.
- TCP Slow Start (the ~14 KB rule of thumb)3: Modern TCP connections send only a limited amount of data in the initial round‑trip, controlled by the initial congestion window. A commonly cited practical payload budget for the first congestion window, after headers and protocol overhead, is roughly 14 KB. If your HTML (including inlined critical styles and any early scripts) is larger than that, the browser may need multiple round‑trips just to receive the
<head>CSS needs to draw the first frame. That pushes out FCP and LCP.
For background, see, for example, Ilya Grigorik, High Performance Browser Networking (O’Reilly, 2013), chapter “Optimising for TCP”: https://hpbn.co/optimizing-for-tcp/
Keeping your initial HTML + inlined critical CSS comfortably under that first‑round‑trip budget is a good target when you’re designing a Critical CSS strategy.
Case Study: Critical CSS Optimisation for a WordPress Page
Test Setup and WebPageTest Parameters
The following WebPageTest / Catchpoint experiment compares three variants of the same WordPress page, tested under the same synthetic conditions.
Test Parameters

Here are the Test Parameters shown in the screenshot:
- Test URL: https://foxscribbler.com/horizontal-scroll-with-css-scroll-driven-animation/
- Connection: 4G (9 Mbps, 170ms RTT)
- Browser Dimension: 1920×1080
- Number of Runs: 1
- Repeat View: Disabled
- Tests Performed: Both (Site Performance and Lighthouse)
- Location: Taiwan
- Third-party Blocks: Google Analytics
Performance demo setup: For demonstration purposes, one of the stylesheets is intentionally delayed by 3 seconds using Requestly (the Elementor frontend CSS file). This highlights how inlining Critical CSS and loading non‑critical styles asynchronously can keep the page usable and visually stable even when some CSS arrives late.
function delay_critical_assets(){
if( is_page( 23418 )) {
wp_enqueue_style( 'delay-stylesheet', 'https://app.requestly.io/delay/3000/https://foxscribbler.com/wp-content/plugins/elementor/assets/css/frontend.min.css', 'array()', null , 'all');
}
}
add_action('wp_enqueue_scripts','delay_critical_assets', 1);
Scenario 1: No optimisation (baseline)
This is the default, unoptimised behaviour: render‑blocking stylesheets in the <head>, no Critical CSS, and no removal of unused assets.
Key results from WebPageTest (Google Analytics blocked):

- First Contentful Paint (FCP): 4397 ms
- Largest Contentful Paint (LCP): 4397 ms
- Cumulative Layout Shift (CLS): 0.01
- Total Blocking Time (TBT): NA (not reported in this run)
- Time To Interactive: 4397ms
- Speed Index: 4573 ms
- Test URL: https://portal.catchpoint.com/UI/Entry/WPTITP/ARHk-C-E-mNBnUmjefjf5DwAA-N
- Document / HTML Size: 48KB
You can think of this as representative of many real‑world pages before any CSS or JS optimisation is applied.
Scenario 2: Inline used CSS
In this variant, only the used CSS is inline, but the rest are set to the default configuration.

Key results (Google Analytics blocked):
- First Contentful Paint (FCP): 4000 ms
- Largest Contentful Paint (LCP): 4000 ms
- Cumulative Layout Shift (CLS): 0.01
- Total Blocking Time (TBT): 88ms
- Time To Interactive: 4271ms
- Speed Index: 4307ms
- Test URL: https://portal.catchpoint.com/UI/Entry/WPTITP/ARHy-C-E-mNBqsmjegiXNH8AA-N
- Document / HTML Size: 146KB
FCP and LCP improve substantially versus the baseline, but note how the HTML size balloons. That has implications for bandwidth, TTFB, and caching, especially when users browse multiple pages.
Scenario 3 – Full Optimisation (Critical CSS + Other Fixes)
The fully optimised variant applies a broader set of improvements:
- Splits CSS into critical and non‑critical parts, inlining only Critical CSS and loading the rest asynchronously
- Removes unused JavaScript
- Preloads critical assets such as web fonts, the featured image, and key stylesheets
- Resizes and compresses large images

Key results (Google Analytics blocked):
- First Contentful Paint (FCP): 1080 ms
- Largest Contentful Paint (LCP): 1080 ms
- Cumulative Layout Shift (CLS): 0.01
- Total Blocking Time (TBT): NA
- Time To Interactive: 1080 ms
- Speed Index: 1315ms
- Test URL: https://portal.catchpoint.com/UI/Entry/WPTITP/ARC0-C-E-mNBkKQjeekok_kAA-N
- Document/ HTML Size: 76 KB
Performance Results and Key Takeaways
| Metric | No Optimisation (Baseline) | Inline Used CSS | Full Optimised + Remove Unused JS | Total Improvement (%) |
|---|---|---|---|---|
| Performance Score | 59 | 59 | 95 | +61.0% (Improvement) |
| First Contentful Paint (FCP) | 4397ms | 4000ms | 1080ms | -75.4% (Reduction) |
| Largest Contentful Paint (LCP) | 4397ms | 4000ms | 1080ms | -75.4% (Reduction) |
| Cumulative Layout Shift (CLS) | 0.01 | 0.01 | 0.01 | Stable |
| Speed Index | 4573ms | 4307ms | 1315ms | -71.2% (Reduction) |
| Time To Interactive (TTI) | 4397ms | 4271ms | 1080ms | -75.4% (Reduction) |
The numbers will vary for other sites and test conditions, but the pattern is typical:
- Inlining everything can improve first‑view paint timings, but at the cost of HTML size, cacheability, and bandwidth.
- A balanced approach—Critical CSS inlined, non‑critical CSS deferred, plus removal of unused JS and image optimisation—tends to give the best overall experience.
Manual vs Automated Critical CSS for WordPress
Generating high‑quality Critical CSS reliably requires the right tools and a clear process 4. At a high level, you:
- Remove obviously unused or non‑critical CSS.
- Identify the viewports that matter most for your users.
- Extract the Critical CSS for those viewports.
- Merge, deduplicate, and minify the extracted rules.
- Wire the Critical CSS into your templates (e.g. WordPress) and load the rest of the CSS asynchronously.
This workflow produces a smaller, focused critical subset and leaves the main stylesheet slimmer and easier to cache.
Why I Prefer Manual Critical CSS Over LiteSpeed Cache
If you’re on a LiteSpeed server, LiteSpeed Cache plus QUIC.cloud can automate Critical CSS, Unique CSS (used‑CSS), and related page‑optimisation tasks 5. That’s often a great choice. In my case, I prefer a manual / script‑driven approach for a few reasons:
- Free‑tier quotas and daily limits: QUIC.cloud’s free tier gives you a fixed monthly quota 6 of Page Optimisation requests (CCSS, UCSS and Viewport Images). On large sites, especially if you enable “CCSS per URL”, you can hit that quota quickly. Once you exhaust the free allowance and any purchased quota, new Critical CSS jobs are queued or paused until quota is available again.
- Queue priority: QUIC.cloud processes a very large volume of optimisation jobs. Paid quotas and higher tiers (LiteSpeed Enterprise, QUIC.cloud Partner) have access to larger monthly allowances and can avoid some of the constraints of the Basic free tier. On busy days, free‑tier jobs may complete more slowly as the service prioritises higher-tier and paid requests.
- Simple layout: My layout is relatively straightforward and consistent, so I don’t run into many edge cases or compatibility challenges that automated tools are designed to handle. That makes a custom, script‑based approach more predictable for my site.
- Precision and stability: By generating Critical CSS tailored to my actual user viewports, I can be stricter about what is allowed into the critical path. That helps prevent flash of unstyled content (FOUC) and reduces the risk of cumulative layout shift (CLS) caused by late‑loading fonts or layout styles, while keeping the site maintainable.
If that level of control feels too involved, a high‑quality plugin is a very reasonable alternative, especially if you’re happy to work within its quota model or are on a paid tier.
Best WordPress Plugins for Critical CSS Automation
If a manual workflow feels too technical, you can use plugins that automate the Critical CSS process end‑to‑end. Options in the WordPress ecosystem include:
- FlyingPress – generates and inlines Critical CSS, defers non‑critical CSS, and integrates with other performance best practices.
- WP Rocket – offers remove‑unused‑CSS and load‑CSS‑asynchronously features, including automatic Critical CSS generation.
- Swift Performance Pro – includes Critical CSS generation and CSS/JS optimisation features. The Free/Lite plan generates Critical CSS based on the CSS used, whereas the Pro plan generates it based on the viewport.
- LiteSpeed Cache (on LiteSpeed servers) – tightly integrated with QUIC.cloud’s Critical CSS and Unique CSS services.
All of these are capable tools; the right choice depends on your stack, hosting (e.g. LiteSpeed vs Nginx/Apache), and budget.
Tools & Prerequisites for generating critical CSS manually
Before you start extracting Critical CSS yourself, set up a small local toolchain:
- Visual Studio Code (VS Code): A convenient editor with an integrated terminal, ideal for managing your script and project files.
- Node.js: Install the required packages to run the automation script and the Critical / PostCSS tooling.
If you use an online Penthouse‑based generator, you won’t need Node.js locally, but you’ll also lose the ability to:
- Handle multiple viewports in one pass.
- Post‑process the output to remove duplicates and merge selectors.

Step-by-Step: Generating Critical CSS Manually
Critical CSS is about loading only the styles needed for the content initially visible to the user. A practical workflow looks like this:
- Clean up obviously unused or non‑critical CSS.
- Identify the important viewports (mobile and desktop) based on your analytics.
- Extract Critical CSS for those viewports.
- Merge, deduplicate, and minify the result.
- Wire the generated file into your templates and inline it in the
<head>.
Planning these steps up front keeps the process organised and reduces surprises.
Step 0: The Prerequisite (generate used CSS)
Before generating the critical path, ensure your used CSS is optimised, remove unnecessary or duplicate styles you know and make sure you’re logged out; otherwise, backend styles will all be included, which makes removing unused styles more challenging.
Before generating the critical path, make sure your used CSS that is reasonably tidy:
- Remove obviously unnecessary or duplicate rules you recognise.
/*! CSS Used from: Embedded */ - Make sure you’re logged out of WordPress (or any admin UI) when collecting “used CSS”, otherwise admin‑bar and backend styles will be included.
- Where you know the page structure, you can omit footer‑only stylesheets, CTA sections that never appear above the fold, or other late‑page styles. That speeds up extraction and reduces the chance of conflicts.
If you haven’t produced a used‑CSS bundle yet, refer to your “Remove Unused CSS with a Chrome Extension” guide first. Once your used.css file is ready, you’re ready to extract Critical CSS from it.
Step 1: Identify Real-World Viewports (Mobile and Desktop)
Critical CSS is always relative to what the user sees first.
- Choose at least one mobile viewport
(375 x 812) and one desktop viewport (1920 x 1080) that match your real users. - To identify viewports in Google Analytics, use
Reports > Tech > Overview > Click the Screen Resolutions linkand identify your website’s most common screen resolutions. - Base your
dimensionslist for the Critical tool on those real‑world viewports. If I generate Critical CSS for very different dimensions (800 x 600or1366 x 768) from what users actually have, you’re more likely to see Flash Of Unstyled Content (FOUC) or layout shifts.

Step 2: Tools for Generating Critical CSS (Penthouse, Critical, PostCSS)
To get a clean result, this guide uses:
- Penthouse: Opens your page in a headless browser for a given viewport and finds which CSS rules are visible on screen.
- Critical (by Addy Osmani and contributors): Wraps Penthouse and can scan multiple device sizes, then merge the results.
- postcss-combine-duplicated-selectors: Detects duplicate selectors (e.g. repeated
.btnrules or :root) and merges them into a single rule. - cssnano: Minifies the CSS by stripping whitespace, comments, and other redundancy.
- fs-extra: A small utility for file and directory handling, which keeps your script simpler and more robust.
Step 3: Set Up Your Local Workspace
With your tools ready, create a workspace for your scripts by following these steps:
Create Your Project Folder
Start by creating a dedicated workspace on your computer.
- Right-click on your Desktop (or preferred directory).
- Select New > Folder.
- Name the folder descriptively, for example,
critical-css-extractor.


Open the Folder in VS Code
- Open Visual Studio Code (VS Code).
- Go to
File > Open Folder… and select the folder you just created. For me, it iscritical-css-generator - You should now see your folder appear in Visual Studio Code


Critical-css-extractor or the folder you’ve created
Initialise the Project with NPM
Open the integrated terminal in VS Code (View → Terminal) and run:
- Open the Integrated Terminal in VS Code (Press
Ctrl + `). - Type the following command and hit Enter:


npm init -y
This creates a package.json file so npm can track your dependencies.

Install Required Dependencies for Critical CSS
Still in the terminal, run:
npm install critical postcss postcss-combine-duplicated-selectors cssnano fs-extra
After this, you’ll see a node_modules/ directory and a package-lock.json file. Don’t delete these; your script depends on them.

Create the recommended folder structure
A simple layout looks like this:
critical-css-extractor/
├── dist/
│ └── css/
│ ├── used.css # Your starting “used CSS” file
│ └── critical.css # The final Critical CSS output
├── node_modules/ # Created by npm install
├── package.json # Created by npm init -y
├── package-lock.json # Created by npm install
└── critical-gen.mjs # Your generation script
Place your used.css file in dist/css/used.css.
Step 4: Create a Critical CSS Generation Script
Create critical-gen.mjs in your project root and paste this script:
// --- 1. IMPORTING THE TOOLS ---
import { generate } from 'critical'; // The engine that finds above-the-fold CSS
import fs from 'fs-extra'; // Enhanced file system tool for reading/writing
import postcss from 'postcss'; // The "Swiss Army Knife" for CSS transformation
import cssnano from 'cssnano'; // The professional-grade minifier
import combineSelectors from 'postcss-combine-duplicated-selectors'; // Merges duplicate CSS rules
async function createCritical() {
// Define where your source CSS is and where the optimized version should go
const inputCss = 'dist/css/used.css';
const finalTarget = 'dist/css/critical.css';
try {
// --- 2. VALIDATION ---
// Check if the source CSS file actually exists to avoid a crash
if (!fs.existsSync(inputCss)) {
throw new Error(`Input CSS file "${inputCss}" not found!`);
}
console.log('🚀 Extracting Critical CSS (Desktop, Tablet, Mobile)...');
// --- 3. EXTRACTION PHASE ---
// Critical opens a headless browser and "looks" at your site
const { css } = await generate({
base: './',
src: 'https://foxscribbler.com/', //URL to web page to create critical CSS for
css: [inputCss],
// We scan multiple device sizes to ensure no "flash of unstyled content" (FOUC)
dimensions: [
{ width: 1920, height: 900 }, // Large Desktop
{ width: 768, height: 1024 }, // Tablet
{ width: 375, height: 667 } // Standard Mobile
],
extract: false, // Don't remove styles from the source file; just copy what's needed
// Penthouse configuration (the browser engine)
penthouse: {
timeout: 90000, // Allow 90 seconds for slow-loading pages
renderWaitTime: 2000, // Wait 2 seconds for JS/animations to settle
puppeteer: {
executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
headless: 'new', // Use the modern headless mode
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-gpu']
}
}
});
console.log('🧹 Post-processing: Combining selectors and minifying...');
// --- 4. CLEANUP PHASE (PostCSS) ---
// Critical is great at finding CSS, but it's "messy."
// We pass the result through PostCSS to fix that.
const processedCss = await postcss([
// This merges rules like: .btn { color: red; } and .btn { margin: 10px; }
// into a single: .btn { color: red; margin: 10px; }
combineSelectors({ removeAnywhere: true }),
// This removes comments, extra spaces, and shortens hex codes
cssnano({ preset: 'default' })
]).process(css, { from: undefined });
// --- 5. OUTPUT PHASE ---
// Write the final, polished CSS to your destination folder
fs.writeFileSync(finalTarget, processedCss.css);
console.log(`✅ Success! Clean Critical CSS saved to ${finalTarget}`);
} catch (err) {
// Log any errors (network issues, missing files, or timeout)
console.error('❌ ERROR:', err);
}
}
// Start the process
createCritical();
A detailed explanation of the script is available from ChatGPT.
For a detailed breakdown, right-click generate-gen.mjs. Open it in the integrated terminal and run the script as ChatGPT explains.

Run the script from the VS Code terminal with: node critical-gen.mjs
node critical-gen.mjs
When you run the script, the output should appear as follows:

critical.css file will appear in dist/css/.How to Inline Critical CSS in WordPress
Once you’ve generated critical.css and saved or minified it as critical-css.min.css under wp-content/uploads/assets/criticalcss/ you can inline it in the <head> using a small PHP snippet.
One convenient way to manage this is via the Code Snippets plugin:
1. Install and activate the Code Snippets plugin
Click the Add New button, then paste the code snippet. This will inline critical-css.min.css into the <head> tag with the highest priority.
2. Inlining Critical CSS via Code Snippets.
If you don’t know how to create a stylesheet, follow my Remove Unused CSS tutorial, which shows you how to log in to cPanel and add the stylesheet.

3. Adjust the conditions (e.g. is_page(23418)) and paths to match your setup.
function inline_critical_css() {
// if (is_single() && !has_post_format('video')){- target single post template but exclude video post format
// if (is_single(){ - Target Single post template
// The code currently checks if (is_page(23418)). This means the CSS will only load on the page with the ID 23418.
if (is_page( 23418 )) {
$css_files = [
WP_CONTENT_DIR . '/uploads/assets/criticalcss/critical-css.min.css',
];
echo '<style id="penthouse-ccss/page-23418">';
foreach ($css_files as $file) {
if (file_exists($file)) {
$css = file_get_contents($file);
if ($css !== false) {
echo $css;
}
}
}
echo '</style>';
}
}
add_action('wp_head', 'inline_critical_css', 0);
After saving the snippet and visiting the target page, view the HTML source. You should see your Critical CSS in the <head> inside the <style id="penthouse-ccss/page-23418">…</style> block.

At this stage, the page will still report render‑blocking stylesheets in tools like Lighthouse or WebPageTest, because the main CSS files are still linked synchronously. The final step is to load those non‑critical styles asynchronously.


4. Loading Non-Critical CSS Asynchronously with rel=”preload” 7
To address render‑blocking CSS, you can:
- Load stylesheets asynchronously.
- Defer the application of styles until after a timeout or user interaction (e.g. keyboard/mouse events).
- As an extreme option, inline all used CSS and remove external stylesheets (usually not recommended for larger sites)
A practical, standards‑friendly approach is to use the preload pattern so that CSS files:
- Start downloading early.
- Do not block initial rendering.
- Are applied as full stylesheets once loaded.
Here is a WordPress snippet that changes the default <link rel="stylesheet"> tags into preload tags with an onload handler, but only on specific pages. I use the modified version of Name Hero code snippets.
By default, the script runs on all the pages or posts. If you want to apply it globally, copy and paste the snippet from the Name Hero Code and load it onto your website.
// Apply to Multiple Specific Pages
function add_rel_preload($html, $handle, $href, $media) {
// List your page IDs, slugs, or titles here
$target_pages = array(23418, 'contact-us', 'About Me');
if (is_admin() || !is_page($target_pages)) {
return $html;
}
$html = <<<EOT
<link rel='preload' as='style' onload="this.onload=null;this.rel='stylesheet'" id='$handle' href='$href' type='text/css' media='all' />
EOT;
return $html;
}
add_filter( 'style_loader_tag', 'add_rel_preload', 10, 4 );
After you save this snippet and update your page, WebPageTest or Lighthouse should show that previously render‑blocking CSS files now have a non‑blocking status. Combined with inlined Critical CSS, this pattern lets you:
- Render above‑the‑fold content quickly and fully styled.
- Load the rest of your CSS in the background.
- Avoid the caching and bandwidth pitfalls of inlining everything.


Frequently Asked Questions:
- What is Critical CSS?
Critical CSS is the minimal set of CSS rules required to render the above‑the‑fold (initial viewport) content of a page. Instead of loading your entire stylesheet before anything can be painted, you inline only this critical subset so the browser can display useful content faster.
- What are render‑blocking CSS resources?
Render‑blocking CSS resources are stylesheets that the browser must download and parse before it can paint any content that depends on them. If large CSS files are referenced early in the
<head>without being optimised, they delay the critical rendering path and push out key performance metrics like FCP and LCP. - Why is inlining all used CSS usually a bad idea?
Inlining all used CSS can speed up first‑view rendering on a single page, but it usually bloats your HTML, slows down Time to First Byte (TTFB), and prevents efficient caching. Because the CSS is embedded in every HTML document, visitors have to download the same styles on each page view instead of reusing a cached stylesheet.
- When is it OK to inline the full CSS?
Inlining the full CSS can be acceptable for very small, single‑page or landing‑page sites with concise stylesheets. As long as the combined HTML + CSS payload comfortably fits within the first TCP congestion window (roughly 14 KB of payload after headers), you may not suffer from the usual drawbacks of HTML bloat and poor cache reuse.
- Should I use a plugin or generate Critical CSS manually?
Both approaches work. High‑quality plugins like FlyingPress, WP Rocket, Swift Performance Pro, or LiteSpeed Cache (with QUIC.cloud) can fully automate Critical CSS generation and CSS deferral. A manual or script‑driven approach gives you more control, avoids quota limits, and can be more predictable on simple, consistent layouts—but it requires more technical work.
- How can I load non‑critical CSS without blocking rendering?
A common pattern is to convert standard
<link rel="stylesheet">tags into<link rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">.This lets the browser start downloading CSS early without blocking initial rendering. Once loaded, the onload handler switches rel back to the stylesheet so the styles are applied, while the above‑the‑fold content is already styled by inlined Critical CSS
Footnotes
- CSS Wizardry – Harry Roberts, “Critical CSS? Not So Fast!”: https://csswizardry.com/2022/09/critical-css-not-so-fast/ ↩︎
- MDN – Critical rendering path: https://developer.mozilla.org/en-US/docs/Web/Performance/Guides/Critical_rendering_path ↩︎
- Ilya Grigorik, High Performance Browser Networking, “Optimising for TCP” – https://hpbn.co/optimizing-for-tcp/ ↩︎
- web.dev – “Extract and inline critical CSS with Critical”: https://web.dev/articles/codelab-extract-and-inline-critical-css ↩︎
- LiteSpeed Cache Docs – Page Optimization: https://docs.litespeedtech.com/lscache/lscwp/pageopt/ ↩︎
- QUIC.cloud Docs – quotas and free tiers: https://docs.quic.cloud/billing/tiers/ and https://www.quic.cloud/online-services-costs/ ↩︎
- web.dev – “Eliminate render‑blocking resources”: https://web.dev/articles/render-blocking-resources ↩︎

