You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Surfaced by the #4539 desktop main-thread attribution (baseline docs/perf/desktop-mainthread-baseline-2026-07-02.md, PR to land the harness). Decomposing the previously-opaque "Other" bucket, IntersectionObserverController::computeIntersections = ~2.0% of main-thread self-time (173ms in a fast unthrottled run; proportionally larger on real/throttled devices). It's the cleanest new actionable sub-bucket — the render axis's other big pieces are RunTask self-time (→ #4537 yield-to-main) and Style&Layout (→ #4536 forced-reflow).
computeIntersections runs whenever the layout/scroll position changes for every registered IntersectionObserver. WorldMonitor registers observers for viewport-gated panel loading (isPanelNearViewport / the panel-near-viewport gate in data-loader), lazy panel mount, and likely animation/visibility triggers. On a dense dashboard these recompute on every scroll + layout.
Lever (audit, then bound)
Count the live IntersectionObservers on /dashboard (PerformanceObserver/DevTools or a one-off instrument) and which elements each watches.
Bound the cost: (a) coalesce many per-panel observers into a shared root observer with rootMargin; (b) disconnect observers once their one-shot trigger fires (lazy-load / near-viewport gates are one-shot — they shouldn't keep recomputing); (c) widen thresholds to reduce recompute frequency.
Surfaced by the #4539 desktop main-thread attribution (baseline
docs/perf/desktop-mainthread-baseline-2026-07-02.md, PR to land the harness). Decomposing the previously-opaque "Other" bucket,IntersectionObserverController::computeIntersections= ~2.0% of main-thread self-time (173ms in a fast unthrottled run; proportionally larger on real/throttled devices). It's the cleanest new actionable sub-bucket — the render axis's other big pieces areRunTaskself-time (→ #4537 yield-to-main) and Style&Layout (→ #4536 forced-reflow).computeIntersectionsruns whenever the layout/scroll position changes for every registered IntersectionObserver. WorldMonitor registers observers for viewport-gated panel loading (isPanelNearViewport/ the panel-near-viewport gate indata-loader), lazy panel mount, and likely animation/visibility triggers. On a dense dashboard these recompute on every scroll + layout.Lever (audit, then bound)
/dashboard(PerformanceObserver/DevTools or a one-off instrument) and which elements each watches.rootMargin; (b) disconnect observers once their one-shot trigger fires (lazy-load / near-viewport gates are one-shot — they shouldn't keep recomputing); (c) widen thresholds to reduce recompute frequency.scripts/measure-desktop-mainthread.mjs) — thecomputeIntersectionssub-bucket should shrink.Part of #4539 / #4487 (render axis). Sibling levers: #4536 (Style&Layout), #4537 (RunTask/INP).