Skip to content

refactor: add React.memo to performance-critical components#1391

Merged
ChuxiJ merged 1 commit intomainfrom
feat/issue-1365-react-memo
Apr 2, 2026
Merged

refactor: add React.memo to performance-critical components#1391
ChuxiJ merged 1 commit intomainfrom
feat/issue-1365-react-memo

Conversation

@ChuxiJ
Copy link
Copy Markdown

@ChuxiJ ChuxiJ commented Apr 2, 2026

Summary

Wraps frequently-rendered components with React.memo:

  • ChannelStrip (MixerPanel) — prevents re-render when unrelated tracks change
  • SessionClipSlotView — grid slots only re-render on own slot data change
  • SessionSceneStrip — scene rows only re-render on own scene change

ClipBlock and TrackLane were already memoized (verified in codebase).

Test plan

  • npx tsc --noEmit — 0 errors
  • npm test — 3865 passed
  • No behavioral regression

Closes #1365

🤖 Generated with Claude Code

…nSceneStrip (#1365)

Closes #1365

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 2, 2026 07:02
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to reduce unnecessary React re-renders in performance-sensitive UI areas by wrapping frequently-rendered components with React.memo, improving responsiveness in the session grid and mixer.

Changes:

  • Memoized SessionSceneStrip to reduce scene row re-renders.
  • Memoized SessionClipSlotView to reduce slot re-renders.
  • Memoized the mixer ChannelStrip to reduce re-renders across tracks.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/components/session/SessionSceneStrip.tsx Wrapes SessionSceneStrip with React.memo.
src/components/session/SessionClipSlotView.tsx Wrapes SessionClipSlotView with React.memo.
src/components/mixer/MixerPanel.tsx Wrapes ChannelStrip with React.memo inside the mixer panel.
Comments suppressed due to low confidence (1)

src/components/session/SessionSceneStrip.tsx:13

  • React.memo won’t prevent re-renders triggered by Zustand subscriptions. This component subscribes to the full slots array (useSessionStore((s) => s.slots)), so any slot update (even in other scenes) will re-render every SessionSceneStrip, largely defeating the intended per-scene memoization. Consider selecting only the slots for scene.index from the store (ideally via a pre-indexed structure or a selector + equality fn such as shallow) so unrelated slot changes don’t invalidate this component.
export const SessionSceneStrip = React.memo(function SessionSceneStrip({ scene }: SessionSceneStripProps) {
  const launchScene = useSessionStore((s) => s.launchScene);
  const stopScene = useSessionStore((s) => s.stopScene);
  const renameScene = useSessionStore((s) => s.renameScene);
  const slots = useSessionStore((s) => s.slots);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +54 to 55
const ChannelStrip = React.memo(function ChannelStrip({ track, faderHeight, returnTracks }: ChannelStripProps) {
const updateTrack = useProjectStore((s) => s.updateTrack);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

Memoization here depends on prop identity. returnTracks is passed as an array prop, and in MixerPanel it’s computed via project.returnTracks ?? [] (which creates a new empty array when undefined). That can cause ChannelStrip to re-render even when track is unchanged, reducing the benefit of React.memo. Consider stabilizing the returnTracks reference (e.g., reuse a module-level empty array / memoize) or avoid passing an array that frequently changes identity.

Copilot uses AI. Check for mistakes.
}

function ChannelStrip({ track, faderHeight, returnTracks }: ChannelStripProps) {
const ChannelStrip = React.memo(function ChannelStrip({ track, faderHeight, returnTracks }: ChannelStripProps) {
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

This PR closes #1365, but the issue’s acceptance criteria also call out additional work (e.g., splitting/memoizing EffectCard and memoizing SessionView). If those are intentionally out of scope for this PR, it would be better to avoid closing the issue (or update the issue/PR description to reflect what remains) so tracking isn’t lost.

Copilot uses AI. Check for mistakes.
@ChuxiJ ChuxiJ merged commit 394349a into main Apr 2, 2026
10 checks passed
@ChuxiJ ChuxiJ deleted the feat/issue-1365-react-memo branch April 2, 2026 07:21
ChuxiJ added a commit that referenced this pull request Apr 3, 2026
…nSceneStrip (#1365) (#1391)

Closes #1365

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

refactor: Add React.memo to performance-critical timeline components

2 participants