docs(30): create phase plan
Phase 30: Component Memoization - 1 plan in 1 wave - Wrap JKSessionAudioInputs with React.memo - Wrap JKSessionRemoteTracks with React.memo - Ready for execution Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
125a7cdcc2
commit
4fb81ea93e
|
|
@ -63,10 +63,10 @@ Plans:
|
|||
2. JKSessionRemoteTracks wrapped with React.memo
|
||||
3. Track components only re-render when their specific track data changes
|
||||
4. React DevTools shows stable render counts for memoized components
|
||||
**Plans**: TBD
|
||||
**Plans**: 1 plan
|
||||
|
||||
Plans:
|
||||
- [ ] 30-01: TBD
|
||||
- [ ] 30-01-PLAN.md — Wrap JKSessionAudioInputs and JKSessionRemoteTracks with React.memo
|
||||
|
||||
### Phase 31: Selector Optimization
|
||||
**Goal**: Redux selectors compute efficiently with memoization
|
||||
|
|
@ -105,7 +105,7 @@ Plans:
|
|||
|-------|-----------|----------------|--------|-----------|
|
||||
| 28. VU Meter Optimization | v1.7 | 2/2 | ✓ Complete | 2026-03-05 |
|
||||
| 29. Context Optimization | v1.7 | 1/1 | ✓ Complete | 2026-03-05 |
|
||||
| 30. Component Memoization | v1.7 | 0/TBD | Not started | - |
|
||||
| 30. Component Memoization | v1.7 | 0/1 | Planned | - |
|
||||
| 31. Selector Optimization | v1.7 | 0/TBD | Not started | - |
|
||||
| 32. State Update Optimization | v1.7 | 0/TBD | Not started | - |
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
---
|
||||
phase: 30-component-memoization
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- jam-ui/src/components/client/JKSessionAudioInputs.js
|
||||
- jam-ui/src/components/client/JKSessionRemoteTracks.js
|
||||
autonomous: true
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "JKSessionAudioInputs does not re-render when parent re-renders with same props"
|
||||
- "JKSessionRemoteTracks does not re-render when parent re-renders with same props"
|
||||
- "Track components only re-render when their specific track data changes"
|
||||
- "React DevTools shows components as 'Memo' with displayName"
|
||||
artifacts:
|
||||
- path: "jam-ui/src/components/client/JKSessionAudioInputs.js"
|
||||
provides: "Memoized audio inputs container"
|
||||
contains: "memo(function JKSessionAudioInputs"
|
||||
- path: "jam-ui/src/components/client/JKSessionRemoteTracks.js"
|
||||
provides: "Memoized remote tracks container"
|
||||
contains: "memo(function JKSessionRemoteTracks"
|
||||
key_links:
|
||||
- from: "jam-ui/src/components/client/JKSessionScreen.js"
|
||||
to: "JKSessionAudioInputs"
|
||||
via: "stable props from memoized context"
|
||||
pattern: "<JKSessionAudioInputs"
|
||||
- from: "jam-ui/src/components/client/JKSessionScreen.js"
|
||||
to: "JKSessionRemoteTracks"
|
||||
via: "stable props from memoized context"
|
||||
pattern: "<JKSessionRemoteTracks"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Wrap JKSessionAudioInputs and JKSessionRemoteTracks with React.memo to prevent unnecessary re-renders when parent components re-render with unchanged props.
|
||||
|
||||
Purpose: Complete the component memoization chain started in Phase 29. These container components sit between JKSessionScreen (parent) and the already-memoized child components (JKSessionMyTrack, SessionTrackVU, SessionTrackGain). Without memoization, parent re-renders cascade through these containers even when props haven't changed.
|
||||
|
||||
Output: Two memoized container components that skip re-renders when props are shallowly equal.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/Users/nuwan/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@/Users/nuwan/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/30-component-memoization/30-RESEARCH.md
|
||||
@.planning/phases/29-context-optimization/29-01-SUMMARY.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Wrap JKSessionAudioInputs with React.memo</name>
|
||||
<files>jam-ui/src/components/client/JKSessionAudioInputs.js</files>
|
||||
<action>
|
||||
Wrap JKSessionAudioInputs with React.memo following the Phase 29 pattern:
|
||||
|
||||
1. Add `memo` to the React import:
|
||||
```javascript
|
||||
import React, { memo } from 'react';
|
||||
```
|
||||
|
||||
2. Wrap the component definition with memo using named function expression:
|
||||
```javascript
|
||||
const JKSessionAudioInputs = memo(function JKSessionAudioInputs({
|
||||
myTracks,
|
||||
chat,
|
||||
mixerHelper,
|
||||
isRemote = false,
|
||||
mixType = 'default'
|
||||
}) {
|
||||
// existing implementation unchanged
|
||||
});
|
||||
```
|
||||
|
||||
3. Add displayName after the component definition (before export):
|
||||
```javascript
|
||||
JKSessionAudioInputs.displayName = 'JKSessionAudioInputs';
|
||||
```
|
||||
|
||||
4. Keep the existing `export default JKSessionAudioInputs;` unchanged.
|
||||
|
||||
Note: Props are already stable from Phase 29 context memoization. Default shallow comparison is sufficient - do NOT add custom comparison function.
|
||||
</action>
|
||||
<verify>
|
||||
Run syntax check:
|
||||
```bash
|
||||
cd jam-ui && node -c src/components/client/JKSessionAudioInputs.js
|
||||
```
|
||||
Verify memo wrapper present:
|
||||
```bash
|
||||
grep -n "memo(function JKSessionAudioInputs" jam-ui/src/components/client/JKSessionAudioInputs.js
|
||||
```
|
||||
Verify displayName present:
|
||||
```bash
|
||||
grep -n "displayName = 'JKSessionAudioInputs'" jam-ui/src/components/client/JKSessionAudioInputs.js
|
||||
```
|
||||
</verify>
|
||||
<done>
|
||||
JKSessionAudioInputs.js contains:
|
||||
- `import React, { memo } from 'react'`
|
||||
- `memo(function JKSessionAudioInputs` wrapper
|
||||
- `displayName = 'JKSessionAudioInputs'`
|
||||
- Syntax check passes
|
||||
</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Wrap JKSessionRemoteTracks with React.memo</name>
|
||||
<files>jam-ui/src/components/client/JKSessionRemoteTracks.js</files>
|
||||
<action>
|
||||
Wrap JKSessionRemoteTracks with React.memo following the same pattern:
|
||||
|
||||
1. Update the React import to add `memo`:
|
||||
```javascript
|
||||
import React, { useMemo, memo } from 'react';
|
||||
```
|
||||
|
||||
2. Wrap the component definition with memo using named function expression:
|
||||
```javascript
|
||||
const JKSessionRemoteTracks = memo(function JKSessionRemoteTracks({
|
||||
mixerHelper,
|
||||
sessionModel
|
||||
}) {
|
||||
// existing implementation unchanged (includes useMemo for remoteParticipantsData)
|
||||
});
|
||||
```
|
||||
|
||||
3. Add displayName after the component definition (before export):
|
||||
```javascript
|
||||
JKSessionRemoteTracks.displayName = 'JKSessionRemoteTracks';
|
||||
```
|
||||
|
||||
4. Keep the existing `export default JKSessionRemoteTracks;` unchanged.
|
||||
|
||||
Note: This component already uses useMemo internally for remoteParticipantsData. The memo wrapper prevents re-renders when mixerHelper and sessionModel props haven't changed.
|
||||
</action>
|
||||
<verify>
|
||||
Run syntax check:
|
||||
```bash
|
||||
cd jam-ui && node -c src/components/client/JKSessionRemoteTracks.js
|
||||
```
|
||||
Verify memo wrapper present:
|
||||
```bash
|
||||
grep -n "memo(function JKSessionRemoteTracks" jam-ui/src/components/client/JKSessionRemoteTracks.js
|
||||
```
|
||||
Verify displayName present:
|
||||
```bash
|
||||
grep -n "displayName = 'JKSessionRemoteTracks'" jam-ui/src/components/client/JKSessionRemoteTracks.js
|
||||
```
|
||||
</verify>
|
||||
<done>
|
||||
JKSessionRemoteTracks.js contains:
|
||||
- `import React, { useMemo, memo } from 'react'`
|
||||
- `memo(function JKSessionRemoteTracks` wrapper
|
||||
- `displayName = 'JKSessionRemoteTracks'`
|
||||
- Syntax check passes
|
||||
</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
After both tasks complete:
|
||||
|
||||
1. **Syntax verification** (automated):
|
||||
```bash
|
||||
cd jam-ui && node -c src/components/client/JKSessionAudioInputs.js && node -c src/components/client/JKSessionRemoteTracks.js
|
||||
```
|
||||
|
||||
2. **Pattern verification** (automated):
|
||||
```bash
|
||||
grep -l "memo(function" jam-ui/src/components/client/JKSession{AudioInputs,RemoteTracks}.js | wc -l
|
||||
# Expected: 2
|
||||
```
|
||||
|
||||
3. **Manual verification** (optional - user can verify with React DevTools):
|
||||
- Open session screen in browser
|
||||
- Open React DevTools Profiler tab
|
||||
- Record while triggering parent re-render (e.g., toggle a setting)
|
||||
- Check JKSessionAudioInputs and JKSessionRemoteTracks show "Did not render" when props unchanged
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Both components wrapped with React.memo using named function expression pattern
|
||||
- Both components have displayName set for React DevTools visibility
|
||||
- Syntax checks pass for both files
|
||||
- Components will skip re-renders when props are shallowly equal (verifiable with DevTools)
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/30-component-memoization/30-01-SUMMARY.md`
|
||||
</output>
|
||||
Loading…
Reference in New Issue