Files
pulse/docs/release-control
rcourtman 054ef7de13 Merge metrics-only resource deltas by patch shape
The 2026-08-25 evening perf pass re-profiled the remaining frontend
costs on the 50-node mock rig after d5440ff43. Idle main-thread burn on
a throttled phone (~10.5s of long tasks per 30s on the worst-case mock)
and residual warm tab-entry cost both decomposed into per-changed-row
work that ignores what actually changed: every metrics tick deep-cloned,
re-canonicalized, and fully re-merged each patched row, and both store
commits then deep-unwrapped the merged rows again through whole-row
keyed reconciles.

The server's resource delta is a JSON merge patch, so the change shape
is already known. applyResourceStateDelta now records the top-level
keys each patch touched (platformData expanded one level), the
connection store publishes them with the resource revision and unions
them across the bounded history and the hidden-tab deferral set, and
mergeCanonicalResourceDeltaSnapshot takes a fast path for changed
non-host rows whose keys stay within the pass-through metric fields,
the proxmox facet mirror, and the four platformData metric mirror
leaves: the previous display row with just those subtrees cloned in
(a manual plain-data clone — structuredClone's per-invocation setup
dominates at this size). Both commit sites write fast rows as per-key
subtree patches (nested reconcile for records, direct sets for
primitives and platformData leaves) instead of whole-row reconciles,
and the connection store commits aligned ticks per index. Any other
change shape — additions, removals, repeated patches in one frame,
structural keys, agent rows (host coalescing) — keeps the full
clone-canonicalize-merge path, and the fast output is pinned
content-equivalent to it in resourceStateAdapters tests; a websocket
store test pins the per-key change shapes, the meta-history union, and
its unknown-shape contamination.

Measured on the pulse-dev rig (VM-to-VM, 50-node/1500-resource mock,
worst-case RandomMetrics, vs two d5440ff43 baseline runs): mobile-4x
idle long tasks 10.8/10.2s -> 3.9s per 30s; warm Alerts entry 5-rep
median long-task total 3.85s -> 1.52s; mobile warm Overview return
3.8/1.7s -> 1.0s; desktop Backups entry settle 1.06/1.20s -> 0.71s;
warm Storage/Overview sub-tab switch medians flat within rep spread;
desktop cold load and /api/state size unchanged.

Browser-verified on the rig build of this tree: live ticks render
through the fast path with per-cell DOM-vs-store consistency at two
samples 30s apart, zero console errors, desktop and 390px/4x mobile.
2026-08-25 15:40:05 +01:00
..