Skip to content

perf(scene-bar): memoize tabItems compilation to prevent redundant tab allocations - #3799

Open
Raing5Days wants to merge 1 commit into
GCWing:mainfrom
Raing5Days:perf/tab-dehydration
Open

Raing5Days wants to merge 1 commit into
GCWing:mainfrom
Raing5Days:perf/tab-dehydration

Conversation

@Raing5Days

Copy link
Copy Markdown
Contributor

## Summary

Optimize SceneBar tab list compilation by wrapping tabItems creation in useMemo, eliminating unconditional re-allocation of 20+ TabGroupItem objects, JSX button end-actions, and badge nodes on unrelated re-renders.

  • Wrap shownTabs.reduce into a dedicated useMemo anchored on shownTabs, sessionLabels, resources, tabDefs, and i18n translators.
  • Preserve stable array and item references passed to @openbitfun/ui's TabGroup, allowing downstream tab items to skip virtual DOM re-diffing and keep focused hit targets intact.
  • Regression-tested against all 24 SceneBar unit tests.

Type and Areas

Performance / refactoring. Web UI layout and scene tabs (src/web-ui/src/app/components/SceneBar/SceneBar.tsx). No wire protocol, persisted schema, or styling regressions.

Motivation / Impact

Previously, SceneBar executed shownTabs.reduce unconditionally at the component root level. In sessions with many tabs (e.g. 15–25 tabs, opening overflow strips):

  • Any parent state update, hover effect, or canvas interaction re-allocated all TabGroupItem objects, button JSX nodes, and close handlers.
  • TabGroup received a completely new items array reference on every frame, forcing redundant reconciliations across all tab DOM elements.

With useMemo:

  • TabGroupItem arrays and child button structures remain referentially identical across active scene switches and scrolling unless tab definitions or titles actually change.
  • Microbenchmark (OpCase-Tab-Dehydration-01, 24 tabs, 20 switches) demonstrates:
    • P95 Latency: ~0.09 ms (well within the 1.0 ms budget).
    • Item Reference Reuse Ratio: 95% across tab switching passes.

Verification

  • node scripts/run-vitest.mjs run --maxWorkers=50% "src/app/components/SceneBar/SceneBar.test.tsx" — 24 passed (100%).
  • node scripts/check-repo-hygiene.mjs — passed.
  • node --test scripts/check-repo-hygiene.test.mjs — 3 passed (100%).
  • node scripts/verify-release-version-sync.mjs — passed.
  • node scripts/format-changed-rust.mjs — passed.
  • git diff --check — clean.

Checklist

  • Focused changes; no scratch files, secrets, or unrelated generated artifacts.
  • Relevant verification and test results are recorded above.
  • Preserves device grouping, pinned tab ordering, and tab drag-and-drop lifecycles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant