Skip to content

렌더 입자성 캠페인 Phase 1 — 핫패스 격리

통합 기록(형식 표준, Phase 현황·결과·남은 것): 2026-08-24-render-granularity.md

  • 날짜: 2026-08-23 (Phase 0 #604 직후, 오너 결정 D1 (가))
  • 목표: 바인딩을 새로 짓지 않고 스토어 쪽에서 불필요한 통지를 끊어 "라이브 운동 세트 편집 → 조립 루트 재실행 0"을 달성한다. renderCtx 키 계약은 유지, workoutSnapshot의 의미만 "렌더 시점 최신값"으로 바뀐다.

바뀐 것

항목파일내용
Phase 1-1 emit 위생activeWorkoutCommands.tssetWorkoutEditorLocked가 잠금 불변이면 같은 인텐트 객체를 반환
Phase 1-1 emit 위생workoutDraftStore.tsset()이 동일 값(Object.is) 패치는 통지 생략
Phase 1-2 스냅샷 비반응화workoutDraftStore.ts · workoutDraftController.tsworkoutSnapshot을 반응 상태에서 제거, workoutSnapshotRef 단일 저장. commitWorkoutSnapshot은 ref 기록만. 어댑터는 렌더 시점 ref 읽기로 같은 키를 제공
Phase 1-3 이벤트 시점 소비자mobileApp.tsx · workoutWriteController.ts · appController.tsxleaveWorkoutForTab·discardActiveWorkout이 ref를 읽음. write env에서 workoutSnapshot 값 제거, renderCtx에 workoutSnapshotRef 추가
Phase 1-4 appController 부속appController.tsxnav 미러에서 스냅샷 제거 + flow 복원(#338에서 빠졌던 topOpenLayer의 읽기 키), 복원 가드는 ref 읽기

검증

  • 행동 계약: workoutDraftStoreGranularity.test.mjs 7계약 — 편집 중 휘발/내구 발행 통지 0 (ref는 최신), 동일 값 setter 통지 0·변경 시 1, 제목 변경 발행 통지 1, 잠금 전이 통지· 불변 시 인텐트 객체 유지, 스냅샷 커밋은 ref만, 인텐트 전이는 통지. 기존 workoutDraftStore.test.mjs 5계약 재조준(스냅샷 단언 → ref).
  • 소스 슬라이스: controllerBoundaries.test.mjs 커밋 슬라이스를 "ref 기록 + set/emit 부재"로 재조준(pending-changes 기존 항목에 사유 병합).
  • 전 체인 npm run check 1771/1771 · check:unused · check:dual-key 초록.
  • 로컬 스택 test:e2e-local 8/8 · 브라우저 회귀 CASE-001·011·015 3/3(프로덕션 빌드).

전후 계측 (Phase 0-2 계측기, 개발 React · CPU 4×)

상호작용루트 커밋 전 → 후커밋 전 → 후커밋 시간 합 전 → 후
① 세트 입력 1회 (×10)2 → 03 → 177~137 ms → 3~8 ms
① 세트 행 추가2 → 03 → 198 → 7 ms
① 세트 완료 체크2 → 03~5 → 1~3108~129 → 9~19 ms
① 운동 시작3 → 25 → 4205 → 147 ms
② 달력 이전 달(미적재)6 → 66 → 6불변(범위 밖)
③ 로그테이블 셀 열기2 → 24 → 4불변(범위 밖)

남은 커밋 1회는 WorkoutFlow 자체의 state 렌더(화면이 원천)다. 편집 중 탭 이탈 persist· 취소·저장이 최신 스냅샷을 쓰는 것은 ref 전환 + CASE-001·011·015로 확인했다.

구조적으로 남는 것

  • 통지 수 계약 — "콘텐츠 발행은 구독자를 깨우지 않는다"가 스토어 행동 테스트로 잠겼다.
  • 핫 키 규칙 — env/ctx에 고빈도 값은 값이 아니라 ref·getter로 넘긴다. (a) 캠페인의 setEnv 렌더 주입 관용구는 "루트가 모든 변화에 재렌더한다"에 기대고 있었고, 입자성은 바로 그 전제를 지운다. 같은 키를 렌더 값으로 다시 싣는 PR은 이 규칙 위반이다.

다음

  • D2(중단 기준선) 재상정: 시나리오 ②(미적재 월 이동 루트 커밋 6)·③(셀 열기 2)의 Phase 2~4 진행 여부. D4(Phase 5 ui/** 방침)는 캠페인 마지막에 리마인드.