mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
Every card instance attached its summary-panel runtime through import().then(), even when the chunk had loaded long ago. The first render therefore measured a header without summary controls; the controls arrived a beat later, the stage shrank, the deferred refit opened a `stage-resize` continuity candidate and the first HA tick paid three extra render passes (Full Performance: blend stateUpdate1 50 → 130 ms, overlay 217 → 809 ms; locally 4 performUpdate per tick instead of 1). summary-runtime-loader.ts separates the summary code from its state: the loaded factory is cached per page, every host builds its own runtime from it (no shared preferences, drafts, subscriptions, timers or DOM). A warm factory yields the runtime synchronously in connectedCallback, before the first Lit render; a cold mount still pays one lazy import, concurrent cold mounts share the pending import, a failed import is forgotten so the next connection retries, and a disconnect cancels the pending attachment of that connection. SummaryRuntimeSlot owns the per-host lifecycle so the card core stays under its line ceiling. Witnesses: loader unit tests (distinct instances, shared pending import, cancelled attachment, retry after failure); demo/smoke_summary_warm_attach (warm replacement and cold-key instance on a warm page own the runtime before the first render, header/stage stable from the first frame, no stage-resize, one performUpdate per geometry-neutral tick, a real viewport resize still opens stage-resize); mutant summary-runtime-attaches-after- first-render. smoke_summary_panel waited for `_summary` as a readiness proxy; it now waits for the server config load, which stays asynchronous. Local paired glow benchmarks (4× CPU throttle): blend 159.7 → 49.9 ms and overlay 326.7 → 120.4 ms at stateUpdate1 with renders 4 → 1; the isometric load loses the three summary-owned long tasks. Docs screenshots: all 11 frames decode pixel-identical to the committed ones; the manifest carries only the new source fingerprint. Initial View ceiling recentred 299 100 → 299 600 for the +299 B loader. Issue: #506 User-Visible: yes