perf: rework PostCSS pipeline (purge-first order, cssnano default, browserslist)#2051
Merged
Conversation
…owserslist)
- Reorder plugins to purgecss -> autoprefixer -> cssnano so prefixing and
minification only run on rules that survive the purge.
- Drop the cssnano `advanced` preset (and the cssnano-preset-advanced dep) for
the `default` preset: advanced was measured to add < 0.2% over default, while
dropping cssnano entirely costs ~5-8%, so default is kept.
- Pin Bootstrap 5.3.8's browserslist in package.json so autoprefixer targets the
browsers Bootstrap itself supports instead of autoprefixer's implicit defaults.
- De-duplicate config: exampleSite/config/postcss.config.js now re-exports the
theme root config. Hugo restricts the PostCSS Node process to the site dir, so
the exampleSite widens security.node.permissions.allowread to '../config'.
- Trim the safelist: drop the d-{bp}-table-cell regex (render-table.html emits
the configured breakpoint class into the markup, so it reaches hugo_stats.json
and survives purge on its own now that purge runs against complete stats), and
document why every remaining entry is JS-injected and cannot be seen in stats.
exampleSite purge-ON build: green, deterministic (run-vs-run 0-diff), selector
audit 0 over-purges, 257,473 B (46,539 gzip, slightly under stock).
✅ Deploy Preview for gethinode-demo ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
# Conflicts: # pnpm-lock.yaml
markdumay
enabled auto-merge
July 17, 2026 17:01
Collaborator
Author
|
🎉 This PR is included in version 3.5.5 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Reworks the PostCSS config so purge runs first and the pipeline ships fewer bytes with fewer
dependencies:
purgecss → autoprefixer → cssnano(wasautoprefixer → cssnano → purgecss). Prefixing and minification now only touch rules that survive the purge.advanced→defaultpreset and drop thecssnano-preset-advanceddependency.Measured on the exampleSite:
advancedadds < 0.2% overdefault, while dropping cssnanoentirely costs ~5–8% — so cssnano stays on the default preset.
package.jsonso autoprefixer targets Bootstrap'sown supported browsers rather than autoprefixer's implicit
defaults.exampleSite/config/postcss.config.jsnow re-exports the theme rootconfig. Hugo restricts the PostCSS Node process to the site dir
(
security.node.permissions.allowread), so the exampleSite widensallowreadto'../config'./^d-(sm|md|lg|xl|xxl)-table-cell$/regex —render-table.htmlemits the configured-breakpoint class into the markup, so it reaches
hugo_stats.jsonandsurvives purge on its own now that purge runs against complete stats. Every remaining safelist
entry gets a one-line reason (all are JS-injected classes PurgeCSS cannot see in stats).
Evidence (exampleSite, purge-ON,
hugo --gc --minify)main.css257,473 B / 46,539 B gzip — slightly under the prior advanced-presetbuild (257,673 / 46,612).
-webkit-, 23-moz-.hugo_stats.jsonthat has a rule in the unpurged CSSsurvives purge — 0 genuine over-purges (an ancestor-aware audit; the only naive flags were
.hero-image-full-height .hero-*compound rules whose ancestor class is unused, correctly purged).Part of the styles-pipeline modernization program (slice S3). Held pending the maintainer
merge gate. Note: S2 (guarded
style.purgedefault flip) will follow and its QA runs against this config.