Follow-up to #304 and #505. With only-include-used-components in place, 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 only-include-used-components
Same fail-safe philosophy as #505 — when in doubt, include:
- Scan sources for literal
fr-(m|p)[trblxvy]?-* classes → allowlist of used utilities.
- 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).
- 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.
Follow-up to #304 and #505. With
only-include-used-componentsin place, the consumer-side floor of the DSFR stylesheet iscore— 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)
fr-m*-*/fr-p*-*min-width:48emblock (1,053 responsive selectors)@mediablocks48em, 5.1 kB forced-colorsfr-grid/fr-colfr-text-*,fr-h*,fr-display)@font-faceMost 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-utilitiesin only-include-used-componentsSame fail-safe philosophy as #505 — when in doubt, include:
fr-(m|p)[trblxvy]?-*classes → allowlist of used utilities.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).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.