Skip to content

Commit

Permalink
Optimize generated CSS by removing unused selectors (#2008)
Browse files Browse the repository at this point in the history
Hugo generates stats about the HTML elements, IDs and classes that can be found in the website,
and we post-process the rendered CSS with postcss-purgecss that uses those stats to remove unused selectors.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
  • Loading branch information
zecakeh authored Dec 10, 2024
1 parent 54d872e commit 1accb9e
Show file tree
Hide file tree
Showing 8 changed files with 1,237 additions and 276 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ _rendered.rst
/spec/
changelogs/rendered.*
.hugo_build.lock
hugo_stats.json
1 change: 1 addition & 0 deletions changelogs/internal/newsfragments/2008.clarification
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Optimize generated CSS by removing unused selectors.
2 changes: 2 additions & 0 deletions config.toml → config/_default/hugo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Default settings.

baseURL = "/"
title = "Matrix Specification"

Expand Down
6 changes: 6 additions & 0 deletions config/production/hugo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Settings only required when the website is built for production.

# Enable stats to use them to optimize the CSS.
[build]
[build.buildStats]
enable = true
38 changes: 38 additions & 0 deletions layouts/partials/head-css.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{{- /*

A modified version of the head-css.html partial of Docsy, that adds a call to
`resources.PostProcess`, allowing post-processing of the generated CSS to
remove unused selectors.

*/ -}}

{{ $scssMain := "scss/main.scss" -}}
{{ $css := resources.Get $scssMain
| toCSS (dict "enableSourceMap" (not hugo.IsProduction)) -}}

{{/* NOTE: we only apply `postCSS` in production or for RTL languages. This
makes it snappier to develop in Chrome, but it may look sub-optimal in other
browsers. */ -}}

{{ if eq .Site.Language.LanguageDirection "rtl" -}}
{{ $css = $css
| postCSS (dict "use" "autoprefixer rtlcss" "noMap" true)
| resources.Copy (replace $scssMain "." ".rtl.") -}}
{{ else if hugo.IsProduction -}}
{{ $css = $css | postCSS -}}
{{ end -}}

{{ if hugo.IsProduction -}}
{{ $css = $css | minify | fingerprint | resources.PostProcess -}}
<link rel="preload" href="{{ $css.RelPermalink }}" as="style" integrity="{{ $css.Data.Integrity }}" crossorigin="anonymous">
{{ end -}}

{{ with $css -}}
<link href="{{ .RelPermalink }}" rel="stylesheet"
{{- with .Data.Integrity }} integrity="{{ . }}" crossorigin="anonymous"{{ end -}}
>
{{ else -}}
{{ errorf "Resource not found or error building CSS: %s" $scssMain -}}
{{ end -}}

{{- /**/ -}}
Loading

0 comments on commit 1accb9e

Please sign in to comment.