codegouvfr / codegouvfr/react-dsfr

optimize-css: opt-in trimming of the spacing utility grid in core (~78 kB raw / ~11.5 kB gzip)

Abierto
#508 0 comentarios 0 reacciones 1 asignado Reclamado por @kevbarns Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
496
Forks
99
Merge medio
15 h 36 min
PR fusionados (30 d)
4

Descripción

Follow-up to #304 and #505. With component trimming in place (#505, now `optimize-css`), the consumer-side floor of the DSFR stylesheet is `core` — shipped as a single block regardless of usage.

## Measured breakdown of core.main.min.css (dsfr 1.14.x, 172 kB raw / 25 kB gzip)

| Family | Raw weight | Notes |
|---|---|---|
| Base / reset / HTML elements | ~62 kB | base typography, forms, lists — hard to split safely |
| **Spacing utilities `fr-m*-*` / `fr-p*-*`** | **~39 kB top-level (927 classes) + a large share of the 29 kB `min-width:48em` block (1,053 responsive selectors)** | exhaustive grid of values × sides × breakpoints |
| All `@media` blocks | 45.3 kB | 29.2 kB for `48em`, 5.1 kB forced-colors |
| `fr-grid` / `fr-col` | 6.9 kB + 196 responsive selectors | |
| Typo utilities (`fr-text-*`, `fr-h*`, `fr-display`) | ~1.6 kB | |
| `@font-face` | 1.9 kB | negligible |

Most apps use a small fraction of the spacing grid, so **~50-60 kB raw (~6-8 kB gzip estimated) is the one core family that is both large and trimmable per class** with reasonable guarantees: unlike component CSS, these classes are never toggled by the DSFR runtime (`data-fr-js-*`), so the failure mode of rule-level purging that #505 deliberately avoided does not apply in the same way. The remaining risk is dynamically built class names (`` `fr-mt-${x}` ``).

## Proposal: opt-in `--trim-spacing-utilities` in `optimize-css`

Same fail-safe philosophy as #505 — when in doubt, include:

1. Scan sources for literal `fr-(m|p)[trblxvy]?-*` classes → allowlist of used utilities.
2. Detect dynamic forms — any template literal or concatenation whose static prefix matches `fr-m`/`fr-p` → **fall back to including the whole family**, with an explicit log line (and a non-silent mode where the fallback is observable in CI).
3. Separate opt-in from component trimming, so enabling one never silently enables the other.

Tests would need the false-positive cases first (a URL or comment mentioning `fr-mt-`, an over-broad file that contains everything, the dynamic near-miss), not only the nominal ones.

If the approach sounds right I can put together a PR along the lines of #505/#506.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.