docs(pendientes): add performance bottleneck analysis for docs site

User reported slow web load + Chrome `[Violation] 'setTimeout' handler
took 78ms`. Profiled the critical path of `/uix/*` layout and documented
4 ranked bottlenecks as **diferir** (deferred to pre-release polish
since UIX is still in framework-dev phase):

  1. 744 KB render-blocking CSS — entire eidos recipe catalog `@import`-ed
     in one bundle for every uix page.
  2. `ActiveEidos.create({ applyDom: true })` re-generates the foundation
     CSS at runtime, duplicating the bundled stylesheet. Likely source
     of the 78ms violation.
  3. 28 sema modules + 71 lang files eagerly imported at layout boot.
  4. 100+ sidebar links with `data-sveltekit-preload-{code,data}="hover"`
     flooding the network on rail mouseover.

Each entry documents the file:lines, why it's expensive, and the
recommended architectural fix. Ordered cost-to-impact for when polish
sprint starts.

Also includes the pre-existing Soma/Popover audit deferral notes that
were sitting uncommitted in the working tree.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
dev 5 months ago
parent 91ecf87cd5
commit cfbe754299

@ -36,6 +36,14 @@ una pasada larga el mismo día. El contrato canónico es:
| Tests browser del flujo completo (Playwright): inline/modal, kind chip, range state machine, snapshot/cancel, click-outside, Escape | **implementar** — alta cobertura para flujos que ahora dependen de state machine. |
| Sema event al bloquear click cuando `mode='modal'` | **diferir** — útil para screen reader feedback. No bloquea. |
## Soma / Popover — bloqueo detectado durante Words
| Item | Disposición |
| --- | --- |
| Auditar `Popover` como componente propio antes de usarlo para `Words.ToolPopover` | **implementar** — el trigger emite `present` en la traza, pero el estado `open` no queda reflejado de forma fiable en DOM y `Content` puede no montarse. En la demo de `Words`, abrir el editor de link desde el `BubbleMenu` produce `TypeError: Cannot read properties of undefined (reading 'wrapperProps')` en `src/uix/soma/components/popover/popover-provider.svelte.ts`. No es una adaptación específica de `Words`; es deuda de `Soma/Popover` y debe resolverse con su propia demo, tests y audit visual. |
| Revisar `Portal` sólo si la auditoría de `Popover` lo confirma | **diferir** — no modificar `internal/Portal` como efecto lateral de `Words`; aislar primero si el fallo está en trigger/provider/presence/portal. |
| Añadir test browser o harness Svelte para click real de `Popover.Trigger` → `Content` visible | **implementar** — los tests unitarios del provider no cubren el flujo renderizado con `Trigger`, `Portal`, `Content`, `bind:open` y atributos morfo en DOM. |
## Tooltip (warnings pendientes del audit)
| Item | Disposición |
@ -74,6 +82,28 @@ remedia. No se hace barrido proactivo de nada que ya esté PASS.
| **Audit D-7.4** — el array de chips de cada control (size, variant, color) enumera el tipo completo declarado en `types.ts` | **hecho** (`scripts/component-audit.ts`). Parsea `{PascalName}{Prop}` exacto, resuelve alias canónicos (`ControlVariant`, `SelectionVariant`, `ChipVariant`, `MarkerVariant`, `TabsVariant`, `ColorRole`+narrowings) vía `SHARED_VARIANT_VOCAB`. |
| Nuevo: audit que verifique que ninguna Part Eidos consulta `provider.opts.{boolean}Button.current` (composición pura) | **diferir** — chequeo defensivo, low value. |
## Web · performance del docs site
Diagnóstico (2026-05-24): el usuario reporta carga lenta + Chrome marca
`[Violation] 'setTimeout' handler took 78ms`. Profiling identifica 4
cuellos de botella reales, ordenados por impacto. Como UIX está en fase
de desarrollo del framework, todos quedan como **diferir** hasta entrar
en pasada de polish; documentados aquí para no perder el rastro.
| Item | Disposición |
| --- | --- |
| **CSS layout 744 KB render-blocking**: `src/uix/eidos/index.css` `@import`-ea 70+ recipes + `generated/base.css` (213 KB) — total 944 KB. Cada `/uix/*` descarga + parsea todo antes del first paint, la mayoría para componentes que la página no usa. | **diferir** — fix arquitectónico: dejar foundation global (~250 KB: `base.css` + `archetypes.css` + `events.css`) y mover cada recipe `XComponent.css` a un `import` dentro del `.svelte` correspondiente para que Vite lo code-splittee con el JS. Esto requiere migrar la convención del foundation eidos. |
| **`ActiveEidos.create({ applyDom: true })` re-genera todo en runtime**: `apply()` (`src/uix/eidos/active-eidos.svelte.ts:361-389`) corre `renderStaticCss()` + `renderThemeCss()` sincrónicamente, itera `THEME_BASE_RECIPE_TOKENS` (2.884 líneas) + color×scale×role×alpha (>1k declaraciones), inyecta 3 `<style>` tags con `textContent = css`. Es la causa más probable de la violación `setTimeout 78ms` (el `$effect` envolvente se programa vía la cola que Chrome reporta como setTimeout). Además **duplica** el CSS bundleado vía `import '@/uix/eidos/index.css'`. | **diferir + investigar trade-off** — fix conservador (1 línea): `applyDom: false` en `web/routes/uix/+layout@.svelte:302` y depender del CSS bundleado. Pero hay que confirmar primero si runtime theme switching depende de la inyección (theme editors live). Si depende, la solución es hacer `apply()` lazy: cachear el render por `themeId` y solo inyectar overrides cuando `setCssVariables()` se llame. |
| **28 sema modules + 71 lang files eagerly imported en el layout**: `web/routes/uix/+layout@.svelte:10-38` (sema) + `src/uix/langs/components/index.ts` (langs). Añade ~30 KB al chunk del layout, bloquea tree-shaking, cada `/uix/*` registra todos aunque el usuario no abra esos componentes. | **diferir** — fix arquitectónico: registración lazy por componente. Cada componente al montar registra su propio sema/langs pack en lugar de el central en boot. Requiere API nueva (`uix.events.registerPack`/`uix.langs.lazy`) + refactor del patrón de boot. |
| **Sidebar con 100+ links `data-sveltekit-preload-{code,data}="hover"`**: `web/routes/uix/+layout@.svelte:746-769`. Mover el cursor por el rail dispara fetches masivos. Las rutas docs son prerenderizadas — el `preload-data` no aporta nada. | **diferir** — fix barato (5 líneas): quitar `data-sveltekit-preload-data` de los links del rail; cambiar `data-sveltekit-preload-code="hover"` a `viewport` para que precargue al entrar en pantalla, no al hover. Mantener `hover` en topbar/brand. |
**Cuándo abordarlo**: cuando la lib entre en pasada de optimización
pre-release. El orden de ataque sugerido es el inverso del coste:
quitar `preload-data` del rail (10 minutos, ganancia inmediata) → fijar
`applyDom: false` con cache lazy (medio día, gana 50-80ms) → split CSS
por componente (1-2 días, gana el grueso del transfer) → sema/langs
lazy registration (sprint propio).
## Doc debt
| Item | Disposición |

Loading…
Cancel
Save

Powered by TurnKey Linux.