Skip to content

perf: rework PostCSS pipeline (purge-first order, cssnano default, browserslist)#2051

Merged
markdumay merged 2 commits into
mainfrom
styles/s3-postcss-config
Jul 17, 2026
Merged

perf: rework PostCSS pipeline (purge-first order, cssnano default, browserslist)#2051
markdumay merged 2 commits into
mainfrom
styles/s3-postcss-config

Conversation

@markdumay

@markdumay markdumay commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

What

Reworks the PostCSS config so purge runs first and the pipeline ships fewer bytes with fewer
dependencies:

  • Plugin order → purgecss → autoprefixer → cssnano (was autoprefixer → cssnano → purgecss). Prefixing and minification now only touch rules that survive the purge.
  • cssnano advanceddefault preset and drop the cssnano-preset-advanced dependency.
    Measured on the exampleSite: advanced adds < 0.2% over default, while dropping cssnano
    entirely costs ~5–8% — so cssnano stays on the default preset.
  • Pin Bootstrap 5.3.8's browserslist in package.json so autoprefixer targets Bootstrap's
    own supported browsers rather than 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
    (security.node.permissions.allowread), so the exampleSite widens allowread to '../config'.
  • Trim the safelist: drop the /^d-(sm|md|lg|xl|xxl)-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. 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)

  • Green + deterministic: 0 ERROR, 0 panic; run-vs-run byte-identical.
  • Size: main.css 257,473 B / 46,539 B gzip — slightly under the prior advanced-preset
    build (257,673 / 46,612).
  • Prefixes present: 48 -webkit-, 23 -moz-.
  • Selector audit: every class/id/tag in hugo_stats.json that has a rule in the unpurged CSS
    survives 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.purge default flip) will follow and its QA runs against this config.

…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).
@netlify

netlify Bot commented Jul 17, 2026

Copy link
Copy Markdown

Deploy Preview for gethinode-demo ready!

Name Link
🔨 Latest commit 0bac19f
🔍 Latest deploy log https://app.netlify.com/projects/gethinode-demo/deploys/6a5a5e82223ac10007998978
😎 Deploy Preview https://deploy-preview-2051--gethinode-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@markdumay
markdumay enabled auto-merge July 17, 2026 17:01
@markdumay
markdumay merged commit 4c1dfee into main Jul 17, 2026
16 checks passed
@markdumay
markdumay deleted the styles/s3-postcss-config branch July 17, 2026 17:02
@markdumay

Copy link
Copy Markdown
Collaborator Author

🎉 This PR is included in version 3.5.5 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant