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
|
2. JKSessionRemoteTracks wrapped with React.memo
|
||||||
3. Track components only re-render when their specific track data changes
|
3. Track components only re-render when their specific track data changes
|
||||||
4. React DevTools shows stable render counts for memoized components
|
4. React DevTools shows stable render counts for memoized components
|
||||||
**Plans**: TBD
|
**Plans**: 1 plan
|
||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
- [ ] 30-01: TBD
|
- [ ] 30-01-PLAN.md — Wrap JKSessionAudioInputs and JKSessionRemoteTracks with React.memo
|
||||||
|
|
||||||
### Phase 31: Selector Optimization
|
### Phase 31: Selector Optimization
|
||||||
**Goal**: Redux selectors compute efficiently with memoization
|
**Goal**: Redux selectors compute efficiently with memoization
|
||||||
|
|
@ -105,7 +105,7 @@ Plans:
|
||||||
|-------|-----------|----------------|--------|-----------|
|
|-------|-----------|----------------|--------|-----------|
|
||||||
| 28. VU Meter Optimization | v1.7 | 2/2 | ✓ Complete | 2026-03-05 |
|
| 28. VU Meter Optimization | v1.7 | 2/2 | ✓ Complete | 2026-03-05 |
|
||||||
| 29. Context Optimization | v1.7 | 1/1 | ✓ 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 | - |
|
| 31. Selector Optimization | v1.7 | 0/TBD | Not started | - |
|
||||||
| 32. State Update 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