Files
Miguel Angel Simon Sierra 7f167ea7c5 perf(studio): scan the preview document once per timeline derivation
Deriving timeline elements from a clip manifest called
findTimelineDomNodeForClip once per clip, and each of those calls rebuilt
the document's whole candidate set: a `[data-start]` query plus a
four-selector `closest()` on every node it returned. On a 273-clip project
that quadratic pass ran on every manifest message (~1/s) and was the
largest task in the app — 99ms of `getTimelineDomNodes` alone across a
ten-click window, with single frames stretching past 100ms.

The scan is now a TimelineDomPass built once per derivation and dropped
with it. It stays pass-scoped on purpose: the preview document mutates
between manifests, so a cached scan that outlived one would resolve a clip
to a detached node — selecting the wrong element, far worse than a slow
scan. Claiming the resolved node moved into the resolver so a shared pass
can never hand two clips the same element.

Two per-selection costs in the property panel go with it, since every
selection re-renders it: detectAvailableWeights ran nine synchronous
`document.fonts.check()` calls per click and is now cached per family and
cleared on `loadingdone`, and the font dropdown's ~1,500-entry catalogue —
keyed on the selected family, so no memo could hold across clicks — is
only built while the dropdown is actually open.

Measured on a 273-clip / 40-track fixture, production React, headless
Chrome, ten clip selections:

  main-thread script   388ms -> 261ms   (-33%)
  idle, no clicks      648ms -> 297ms   (-54%, 4x CPU throttle)
  longest frame         50ms ->  25ms
  4x throttle p95     41.6ms -> 33.3ms, max 133ms -> 92ms
2026-08-03 22:07:02 -07:00
..
2026-08-02 21:57:19 -07:00
2026-08-02 21:57:19 -07:00
2026-08-02 21:57:19 -07:00