Unminified CSS: how squirrel tells minified from formatted
Stylesheets that read as source rather than build output. squirrel analyses inline CSS and judges linked files by their filename.
What minification removes
Minification strips what only a person needs: newlines, indentation, comments, and the spaces around punctuation. On CSS it typically removes a fifth to a third of the file, and it composes with compression rather than replacing it, because gzip still has less to work with afterwards.
Most bundlers minify CSS in production mode, though some need it turned on explicitly. An unminified stylesheet in production usually means the build ran in development mode, the minifier was never configured, or the file bypassed the build entirely.
What squirrel checks
The rule runs on every crawled page and looks at three sources. It emits one or two checks: either the pass, or one or both of the findings.
unminified-css: warns with the messageN CSS file(s) appear unminified, listing up to five sources with their size and estimated saving. The details carry the total saving and how many more there were.potentially-unminified-css: reports at info status with the messageN stylesheet(s) may not be minified, listing up to five, with the note that these are files whose name has no.minin it.minified-css: passes with the messageCSS appears to be minifiedwhen neither list has anything in it.
Inline <style> content of 2,048 characters or more is analysed directly. A block counts as unminified when any of four signals fires: more than 1% of its characters are newlines, more than three block comments, more than 15% whitespace, or more than ten selector openings followed by a newline. The reason string names whichever fired.
Linked stylesheets are judged by filename only, because the rule does not fetch them. A file is suspected when its name contains none of .min., -min. or .prod., has no dot-or-hyphen followed by eight or more hex characters and another dot, and does not look like a framework, meaning the name contains bootstrap, tailwind or normalize. Files from the crawl’s own resource list are skipped below 2,048 bytes. Stylesheets found only in the markup are judged the same way, with cdn added to the framework list and a required .css ending. A page with no parsed document emits nothing at all.
Elements inside <noscript> are skipped: a browser with scripting enabled reads <noscript> content as plain text, so nothing in it loads or renders. See content inside noscript.
How to fix it
Run the production build. In Vite that minifies CSS by default; esbuild needs --minify and webpack needs a CSS minimiser configured, so check the config as well as the mode.
vite buildFor a stylesheet outside the build, cssnano or clean-css does the same job as a standalone step.
The common false positive is the whole second half of this rule. A file named styles.css that is perfectly minified is still reported at info status, because the rule reads the name rather than the bytes. Renaming to styles.min.css, or letting the bundler hash it, clears it.
| Rule ID | perf/unminified-css |
| Category | Performance |
| Scope | Per-page |
| Severity | warning |
| Weight | 4/10 |
Options
| Option | Type | Default | Description |
|---|---|---|---|
min_size_bytes | number | 2048 | Minimum CSS size in bytes to check for minification |
newline_ratio_threshold | number | 0.01 | Newlines per character ratio threshold for unminified detection |
Configuration example
[rules."perf/unminified-css"]
min_size_bytes = 2048
newline_ratio_threshold = 0.01Enable / disable
Disable this rule
[rules]
disable = ["perf/unminified-css"]Disable all Performance rules
[rules]
disable = ["perf/*"]Enable only this rule
[rules]
enable = ["perf/unminified-css"]enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.
Related rules
- perf/css-file-size: the size those bytes add up to.
- perf/unminified-js: the same analysis on scripts.
- perf/asset-compression: compression, which minification composes with rather than replaces.
- perf/source-maps: the other sign that a build shipped its development output.
Performance findings ship in every audit next to the SEO, security and agent experience rules. See Core Web Vitals for how an agent works through a report.
References
Check your site
Run squirrel audit https://example.com and open the Performance section of the report. Each stylesheet is listed with the reason it was flagged. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.