docs(bundle): Phase 5a done (base.css prune), 5b deferred with rationale

base.css pruned to the 9 role-referenced scales (full palette opt-in):
113.5 → 36.2 KB gz per page total (−68% from the original monolith).
Non-Gregorian calendar lazy-loading (5b) deliberately deferred — it needs
a sync→async change to the vendored date core for a narrow date-pages-only
win; documented the trade-off.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
active-uix
dev 4 months ago
parent 95be3b6cb1
commit c121365bed

@ -19,7 +19,7 @@ excediendo** — y es un problema *estructural* (un agregado monolítico), no de
| JS por página | ✅ Sano | entry 10.4 KB gz · runtime ~35 KB gz · componente mediana 7.3 KB gz |
| CSS por página | ⚠️ Exceso | **113.5 KB gz / 851 KB raw** en *toda* página `/uix` |
| Code-splitting JS | ✅ Correcto | color engine, sema y componentes se cargan bajo demanda |
| Code-splitting CSS | ✅ Resuelto | 93 recipes code-split; index.css foundation-only. **113.5 → 54.4 KB gz/página** (−59 KB). Pendiente: Fase 5 (podar base.css) |
| Code-splitting CSS | ✅ Resuelto | 93 recipes code-split + `base.css` podado a 9 scales. **113.5 → 36.2 KB gz/página** (−68%). |
---
@ -66,7 +66,8 @@ monta la página. Ese eje decide la Fase 1 (`@layer` o no).
| **2** ✅ | Partials compartidos (`menu-indicator` order-independent por especificidad) + primitivas layout en foundation | medio | hecho |
| **3** ✅ | Propagar a los 83 restantes **por lotes** por familia; couplings arreglados (toggle-group, pickers) | medio | hecho |
| **4** ✅ | `index.css` = foundation-only (−59 KB gz/página) | bajo | hecho |
| **5** | (track aparte) podar `base.css` a roles tematizados + calendarios no-gregorianos dynamic import | alto | build |
| **5a** ✅ | podar `base.css` a las scales que usan los roles (9 de 31); resto opt-in en `palette.css` | alto | hecho |
| **5b** ⏸️ | calendarios no-gregorianos a dynamic import | alto | **diferido** (ver abajo) |
**Cross-coupling a vigilar** (recipes agregados que referencian un componente
splitteado): auditado para los 10 — único caso `words.css → [data-textarea]`, y
@ -164,6 +165,46 @@ NumberField/ColorPicker/TextArea) NO necesita el import — el recipe llega solo
barrido (el scoping `[data-{component}]` lo confirma en la práctica).
- `check` 0 errores.
### Fase 5a — `base.css` podado (COMPLETADO)
`base.css` enviaba las **31 scales Radix** donantes, pero los roles del tema solo
referencian **9** (gray·green·indigo·orange·plum·purple·red·slate·teal). Las
otras 22 eran peso muerto en toda página: ningún componente referencia
`--scale-*` crudo (usan `--color-{role}-*`), y el theming runtime construye desde
los datos JS de scales y escribe valores **resueltos** (`build-scheme`:
`variables[k]=hex`), nunca lee los tokens CSS de scale.
- `renderThemeCss` ahora emite solo las scales referenciadas por roles (opción
`scales: 'roleReferenced'`, default). El donante completo de 31 scales va
**opt-in** en `generated/palette.css` (nuevo `renderColorPaletteCss`).
- El **contrato CSS** sigue siendo el vocabulario completo (una app puede
override cualquier scale; carga `palette.css` para usar las 22 extra). El test
de contrato valida cobertura contra la paleta completa (`scales: 'all'`).
- **base.css 53.7 → 35.4 KB gz**. **Monolito (toda página) 54.4 → 36.2 KB gz.**
Acumulado con Fases 0-4: **113.5 → 36.2 KB gz (−68 %)**.
- Verificado en navegador: roles resuelven (primary = purple, `button` bg
correcto), scales podadas vacías en páginas normales, restauradas en
`/temas/color` vía `palette.css`. Suite eidos en baseline (192/195).
### Fase 5b — calendarios no-gregorianos: DIFERIDO (decisión)
`createCalendar(name)` (vendored `@internationalized/date`) es **síncrono** y
hace `import` estático de las 9 clases de calendario → se empaquetan juntas.
Cargar las no-gregorianas bajo demanda exige hacerlo **async**, lo que cambia la
API core del motor de fechas (rompe el supuesto de construcción síncrona,
ramifica a sus llamadores, y **diverge del upstream** vendored).
- **Recompensa**: ~37 KB raw / ~10-12 KB gz, **solo en páginas de fecha**, y solo
para apps que no usan calendarios no-gregorianos. (Ya están code-split fuera
de las páginas sin fecha.)
- **Coste/riesgo**: refactor sync→async de código vendored core, divergencia del
upstream, ripple a motor + componentes.
El trade no compensa: hacer async la API de fechas para ahorrar ~10 KB gz en
páginas de fecha no vale la divergencia/riesgo. Se difiere conscientemente; si
una app real necesita muchos sistemas de calendario y le pesa, se reabre con un
`createCalendarAsync` paralelo (sin romper la API síncrona).
## Metodología
- `npm run build` → `adapter-static`, salida en `build/`.

Loading…
Cancel
Save

Powered by TurnKey Linux.