Skip to content

Add realm properties hooks and reduce main window re-renders.#5858

Draft
michelinewu wants to merge 10 commits into
stagingfrom
mw_rerenders
Draft

Add realm properties hooks and reduce main window re-renders.#5858
michelinewu wants to merge 10 commits into
stagingfrom
mw_rerenders

Conversation

@michelinewu

@michelinewu michelinewu commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Overview
This PR introduces new React hooks (useRealmProperty and useRealmProperties) to minimize unnecessary component re-renders across the application, particularly in the main window.

Issues Addressed

  1. Excessive re-renders - Multiple components were re-rendering when realm properties changed in the realm object, not just the property referenced
  2. Stale values in resize handlers - Chat and other resizable components had debounce/cleanup issues with stale state
  3. Performance in main window and dock - The main window and live dock components were re-rendering too frequently

Solutions Implemented
New Hooks (app/components-react/hooks/realm.ts)

  • Added useRealmProperty - selectively subscribe to individual realm properties
  • Added useRealmProperties - subscribe to multiple specific properties
  • These mirror the existing useVuex hook pattern for consistency

Component Refactoring

  • Refactored Main.tsx (primary change: +84/-44 lines) to use new hooks
  • Updated LiveDock.tsx, SideNav.tsx, and other frequently-rendered components
  • Replaced broader state subscriptions with targeted property subscriptions

Bug Fixes

  • Fixed chat resize bug by adding debounce and cleanup checks to prevent stale values

@michelinewu
michelinewu changed the base branch from master to staging April 22, 2026 18:38
@bundlemon

bundlemon Bot commented Apr 22, 2026

Copy link
Copy Markdown

BundleMon

Files added (4)
Status Path Size Limits
renderer.(hash).js
+7.72MB -
vendors~renderer.(hash).js
+4.67MB -
updater.js
+115.29KB -
guest-api.js
+40.23KB -

Total files change +12.54MB

Final result: ✅

View report in BundleMon website ➡️


Current branch size history

@michelinewu
michelinewu requested a review from wesrupert April 23, 2026 16:18

@wesrupert wesrupert left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, with two small suggestions

Comment on lines +38 to +42
const { currentStep, currentIndex, showOnboarding } = useRealmProperties({
currentStep: prop(OnboardingV2Service.state, 'currentStep'),
currentIndex: prop(OnboardingV2Service.state, 'currentIndex'),
showOnboarding: prop(OnboardingV2Service.state, 'showOnboarding'),
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiousity, is there a benefit to this approach vs the useRealmObjectProperties multi-key signature? From my read of realm.ts changes, this would also be a valid call:

const { currentStep, currentIndex, showOnboarding } = useRealmObjectProperty(
  OnboardingV2Service.state,
  'currentStep',
  'currentIndex',
  'showOnboarding'
);

Comment applies throughout, so I'll just leave it on this one.

const { CustomizationService, EditorCommandsService, SourcesService, AudioService } = Services;

const performanceMode = useRealmObject(CustomizationService.state).performanceMode;
const { performanceMode } = useRealmObjectProperty(CustomizationService.state, 'performanceMode');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, but throughout - this gets pretty verbose in some files, especially when renaming the tracked value. I'd recommend two changes:

  1. Rename useRealmObjectProperty -> useRealmProperty, to match useRealmProperties
  2. If there is only one key (or just make this the "one key only" version, for simplicity/maintainability), return the value directly.

Together, this line would become:

const performanceMode = useRealmProperty(CustomizationService.state, 'performanceMode');

The benefits are better realized in other files, like app/components-react/windows/Settings.tsx:

This:

const { currentSettingsTab: currentTab } = useRealmObjectProperty(
  NavigationService.state,
  'currentSettingsTab',
);

Becomes this:

const currentTab = useRealmProperty(NavigationService.state, 'currentSettingsTab');

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants