Skip to content

ENH: tree-shake unused AMP CSS custom properties + trim @font-face to woff2 - #14234

Draft
hotinglok wants to merge 12 commits into
latestfrom
amp-css-custom-property-treeshake
Draft

ENH: tree-shake unused AMP CSS custom properties + trim @font-face to woff2#14234
hotinglok wants to merge 12 commits into
latestfrom
amp-css-custom-property-treeshake

Conversation

@hotinglok

Copy link
Copy Markdown
Contributor

Why

Builds on #14229. Further reduces the size of the inline <style amp-custom> on AMP article pages to keep well under AMP's 75KB CSS limit.

The inline AMP CSS is assembled from Emotion critical CSS + the concatenated SCSS-module chunks + the active service theme (:root custom-property blocks + @font-face). Two AMP-only passes are added to optimiseAmpCss in _document.page.tsx.

What

  • treeshakeCssCustomProperties — removes CSS custom properties from :root {} blocks that are never referenced via var() in the final CSS. Service themes declare their full palette and font-variant token sets on :root, but a given page references only a fraction. Includes transitive-closure handling so --a: var(--b) keeps --b when --a is used.
  • trimFontFaceSourcesToWoff2 — trims each @font-face src list to its woff2 source (every AMP-capable browser supports woff2), preserving local() and leaving a face untouched if it has no woff2 source.

Both run only on the AMP article path (isAmp && pageType === 'article'), so canonical/Lite are unaffected.

Measured impact

Against the real news theme (latin, 4 font faces, ~6.1KB theme CSS) with the actual transforms:

Transform Saving
tree-shake custom properties ~4.7–5.0KB
woff2 trim ~0.4KB

Tree-shake is the dominant lever: components consume theme colours via compile-time SCSS $ variables (literal hex), so the theme's --brand-*/palette custom properties have effectively no var() consumers in the rendered CSS and are safely removed.

Safety

  • Verified there are zero inline style="" references to var(--…) in the codebase — stylesheets are the only consumer — and AMP runs no custom JS, so the final concatenated CSS string is the single source of truth for what is used.
  • Tree-shake only drops properties unreferenced within the very string it minifies, so it cannot break a live reference.

Tests

  • treeshakeCssCustomProperties/index.test.ts — removal, transitive keep, empty-block removal, non-custom-property preservation, multi-:root/dedup usage.
  • trimFontFaceSourcesToWoff2/index.test.ts — woff fallback removal, multiple legacy formats, local() preservation, no-woff2 untouched, multi-face, no-@font-face untouched.

All 11 unit tests pass; new files pass Prettier.

Notes

  • A dedupe pass was prototyped and dropped — measured ~0 bytes because the theme's :root/@font-face are emitted once and component rules are uniquely scoped, so there are no byte-identical top-level duplicates in this architecture.

Base automatically changed from smaller-bbc-blocks to latest July 17, 2026 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants