Là một dự án frontend, addyosmani/critical đã đạt 10.3k sao trên GitHub, ngôn ngữ JavaScript. Extract & Inline Critical-path CSS in HTML pages
Tóm tắt dựng từ metadata GitHub của chính dự án — chưa có bài review TopGit. Trang sẽ tự động cập nhật khi bài review đầy đủ được xuất bản.
VÌ SAO CHƯA CÓ REVIEW
TopGit viết bài đầy đủ cho repo có nhiều sao nhất và được yêu cầu nhiều nhất. Trang này là snapshot trong thời gian chờ — xem README gốc ở tab READ ME.
Extract the critical-path (above-the-fold) CSS from your HTML, inline it, and load the rest
asynchronously — so the browser can paint the first screen without waiting on a full stylesheet.
Critical removes render-blocking CSS from the critical path, which is one of the most direct
levers on Largest Contentful Paint and first render. It works for static sites, MPAs, and
single-page apps, and it's built to be driven by humans, build pipelines, and coding agents
alike.
npm install --save-dev critical
Contents
How it works
Quick start
Two engines
CLI reference
API reference
Inlining behavior
Tuning the above-the-fold set
MCP server (agents)
Recipes
Design principles
Requirements
Alternatives
How it works
Given an HTML document and its stylesheets, Critical:
Determines what's critical. It figures out which CSS rules style the content that paints
above the fold — either by matching rules against the delivered DOM (fast, no browser) or by
rendering the page in a real viewport (accurate, handles SPAs). See Two engines.
Inlines it. The critical rules go into a <style> at the top of <head> so first paint
needs only the HTML.
Defers the rest. Each <link rel="stylesheet"> is replaced in the head by a
<link rel="preload"> and moved to the end of the body, so it no longer blocks first paint.
No inline scripts are added, so it works under a strict Content Security Policy.
The output is deterministic: the same input produces byte-identical output, so it's safe to run
in CI and diff in version control.
Quick start
CLI
# Optimize a build directory in place (inlines critical CSS, defers the rest)
critical ./dist --inline --write
# See what it would do and why, without writing anything
critical ./dist --explain
# A single file to stdout
critical index.html --inline > index.critical.html
API
import { critical } from "critical";
const { html, css, report } = await critical({
src: "dist/index.html",
inline: true,
});
// `html` — the document with critical CSS inlined and stylesheets deferred
// `css` — the critical CSS on its own (minified)
// `report` — structured diagnostics (engine used, bytes, rules, warnings, timing)
critical() never writes to disk on its own — it returns the result. Use the CLI's --write
/ --out, or write result.html / result.css yourself.
Docker
The container image includes Playwright and Chromium, so both the static and render engines work
without additional setup. Mount the generated site at /site and include critical before its
arguments:
Critical picks the right strategy for each document automatically (engine: "auto", the
default), and tells you which it used and why.
Engine
How it decides what's critical
Needs a browser
Best for
static
Matches CSS rules against the delivered DOM (the used CSS)
No
SSG / SSR / MPA output that ships real markup
render
Loads the page at a real viewport and measures what's painted above the fold
Yes (Playwright)
SPA shells, and when you want a tight, viewport-accurate set
Automatic routing. When engine is "auto", Critical inspects the delivered HTML. If the
document already contains rendered content, the static engine is correct and runs in
milliseconds. If the document is an empty application shell (e.g. <div id="root"></div> with
no markup yet), there's nothing to match against statically, so Critical escalates to the render
engine and measures the page the way a browser actually paints it.
You can always pin the engine explicitly with engine: "static" or engine: "render".
The render engine uses Playwright, declared as an optional peer
dependency. It's imported lazily, so the static path — and the default install — never pull in
a browser. To use the render engine: npm i -D playwright && npx playwright install chromium.
CLI reference
critical <input> [options]
input a directory (all *.html are processed), an .html file, or stdin
Option
Description
Default
-e, --engine <auto|static|render>
Engine selection
auto
-i, --inline
Inline critical CSS and defer the rest
off
-w, --width <px>
Render-engine viewport width
1300
-h, --height <px>
Render-engine viewport height
900
--dimensions <WxH,WxH>
Multiple render viewports (e.g. 390x844,1300x900)
—
--no-fold
Ignore [data-critical-fold] scoping in the static engine
—
--no-minify
Keep the critical CSS readable instead of minifying
—
-o, --out <file|dir>
Write output here instead of stdout
stdout
--write
Rewrite the input file(s) in place (use with --inline)
off
--json
Emit the structured result as JSON
off
--explain
Print the engine decision and stats to stderr
off
--help
Show help
—
Examples
critical ./dist --inline --write # whole build dir, in place
critical index.html --explain # routing decision + size stats
critical app.html -e render -i > out.html # force a real-browser pass for an SPA
critical page.html --dimensions 390x844,1300x900 -i # union of mobile + desktop folds
cat page.html | critical --inline # stdin -> stdout
critical ./dist --json # machine-readable report for CI/agents
html — the document. Identical to the input unless inline is set.
css — the critical CSS, minified (unless minify: false).
report — structured diagnostics:
{
"engine": "static", // engine that actually ran
"reason": "rendered document (…) — matching used CSS without a browser",
"requestedEngine": "auto",
"rules": { "kept": 10, "total": 15 },
"bytes": { "stylesheets": 1107, "critical": 544, "savedBlocking": 1107 },
"stylesheetsDiscovered": ["/styles.css"],
"stylesheetsDeferred": ["/styles.css"], // present when inlined
"warnings": ["…"],
"durationMs": 13,
"deterministic": true,
}
report is designed to be read by a program: it explains the decision, quantifies the win
(savedBlocking = render-blocking bytes removed from the critical path), and surfaces any
caveats as warnings.
Inlining behavior
With inline: true, Critical:
Inserts <style data-critical>…</style> as the first child of <head> so it wins the
cascade race against the deferred sheets.
Stops each <link rel="stylesheet"> from blocking the first paint, using the preload strategy:
<!-- in the head, where the stylesheet was: -->
<link rel="preload" as="style" href="/styles.css" />
<!-- moved to the end of <body>: -->
<link rel="stylesheet" href="/styles.css" />
The preload starts the download early; the stylesheet applies after the above-the-fold content
(already styled by the inlined critical CSS) has painted. There is no inline event handler,
so this works under a strict script-src Content Security Policy, and no <noscript>
fallback is needed — the stylesheet loads normally whether or not JavaScript runs.
Add data-critical-skip to a <link> to leave it untouched. For a strict style-src CSP, pass
inline: { nonce: "…" } to stamp the injected <style> with your nonce.
Tuning the above-the-fold set
[data-critical-fold] (static engine). By default the static engine inlines all used
CSS. Mark the container that holds your above-the-fold content with data-critical-fold and
the static engine scopes matching to that subtree, producing a tighter critical set without a
browser.
Viewports (render engine). Use width/height or dimensions to define exactly what
"above the fold" means. Multiple dimensions union their results — useful for shipping one
critical set that covers both mobile and desktop.
@font-face, @keyframes, custom properties are preserved when referenced; unused
@keyframes and empty @media/@supports/@layer blocks are pruned.
MCP server (agents)
Critical ships a Model Context Protocol server so an agent
can call it as a tool and receive the structured report back directly:
node src/mcp.js # stdio MCP server exposing `optimize_critical_css`
import { createServer } from "critical/mcp";
The tool takes src/html (plus optional css, engine, inline, width, height) and
returns the critical CSS, the rewritten HTML, and the report as structured content. Requires the
optional @modelcontextprotocol/sdk peer dependency.
await critical({ src: "dist/index.html", engine: "render", inline: true });
// auto-routing would also pick "render" here; pinning it just skips the sniff.
Design principles
Two engines, automatically routed. The fast path runs whenever the delivered DOM is the
source of truth; the browser is used only when it's actually needed.
Platform-first, few dependencies. Three runtime dependencies — lightningcss (parse +
minify + dead-code), linkedom (DOM), css-tree (rule walking). Everything else is a Node
built-in (fetch, parseArgs, styleText, fs.glob). Heavy capabilities (playwright, the
MCP SDK) are optional peers, imported lazily — you only pay for what you use.
Deterministic and explainable. Stable output bytes and a structured report that says
what ran, why, and what it saved.
Safe by default. Nothing is written without an explicit flag; deferral adds no inline
scripts, so the output works under a strict Content Security Policy.
Requirements
Node.js ≥ 22.13
The render engine additionally needs playwright and a browser:
npm i -D playwright && npx playwright install chromium. The static engine needs neither.
Alternatives
Critical isn't the only way to inline critical CSS, and it isn't always the right one — a purely
prerendered site that just wants its used CSS inlined may be better served by a lighter,
browser-free tool. For a thorough, fair comparison of Critical, Beasties (formerly Critters),
Penthouse, and native platform approaches — including where each one is the better choice and a
reproducible benchmark — see COMPARISON.md.
Maintainers
This module is brought to you and maintained by the following people:
addyosmani/critical có 10.3k sao GitHub — tải lại trang để xem số mới nhất, hoặc xem trực tiếp github.com/addyosmani/critical. TopGit phản chiếu số sao của GitHub nhưng không cam kết đến từng phút.
addyosmani/critical có những chủ đề gì?
GitHub topics của addyosmani/critical: "critical-css", "critical-path-css", "critical-path-styles", "css", "inline-css", "inline-styles". TopGit xếp repo vào nhóm Frontend.
addyosmani/critical có website riêng không?
TopGit chưa ghi nhận URL trang chủ cho addyosmani/critical. Phần README ở tab phía trên thường có link demo, hoặc xem mô tả GitHub của repo.
addyosmani/critical còn đang phát triển không?
Commit gần nhất trên addyosmani/critical là 13 ngày trước (theo timestamp GitHub). Repo có 393 fork — một chỉ báo về mức độ quan tâm của cộng đồng.
addyosmani/critical dùng license gì?
addyosmani/critical phát hành theo license Apache-2.0. Nên mở file LICENSE trên GitHub để xác nhận — license metadata đôi khi lệch với thực tế dự án.
addyosmani/critical viết bằng ngôn ngữ gì?
addyosmani/critical chủ yếu viết bằng JavaScript. Trường "language" của GitHub dựa trên phần lớn byte ở nhánh mặc định.
Đọc thêm về addyosmani/critical ở đâu?
Trang TopGit này là một snapshot — tab "Readme" hiển thị nguyên văn README của repo (đã bỏ link, giữ ảnh). Repo GitHub ở github.com/addyosmani/critical là nguồn chính thức.
Đọc đầy đủ README ở tab phía trên.
critical có đáng để bạn bỏ thời gian?
ChatGPT, Claude và Perplexity đều đọc được trang này. Hỏi thử xem họ nghĩ gì về critical.