Skip to content

PresentationShared의 View 구성 요소와 렌더링 입력을 분리한다 - #946

Merged
opficdev merged 1 commit into
developfrom
refactor/#884
Oct 28, 2026
Merged

opficdev merged 1 commit into
developfrom
refactor/#884

Conversation

@opficdev

@opficdev opficdev commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

🔗 연관된 이슈

🎯 의도

계산 프로퍼티로 구성한 내부 View는 그 안에서 읽은 상태가 바뀌면 부모 View의 body 전체가 다시 평가되는 구조

상태 변화로 재평가가 필요한 영역만 별도 View로 분리하고, 해당 상태를 부모가 아닌 분리한 View의 body에서 읽도록 구성하여 부모 body의 재평가 범위를 줄이는 것

📝 작업 내용

📌 요약

  • TodoListView, TodoEditorView에서 상태를 읽는 영역을 같은 파일의 private View로 분리

🔍 상세

  • TodoListView
    • 상태를 읽는 영역을 store를 전달받는 private View로 분리
      • TodoListContent: 기존 todoListContent 계산 프로퍼티, todos, isLoading, hasMore를 읽어 목록 구성, 삭제 토스트 표시
      • TodoListTopBar: 기존 topBar 계산 프로퍼티, category, isSearching을 읽어 상단 바 구성, dismiss·openWindow·isiOSAppOnMac과 에디터 열기 담당, matchedGeometryEffect용 @Namespace 소유
      • TodoListSearchBar: 기존 searchBar 계산 프로퍼티, searchQuery를 읽어 검색 입력 구성, @FocusState 소유, Namespace.ID만 전달받음
      • TodoListFilterHeader: 기존 filterHeader 계산 프로퍼티, appliedFilterCount와 query를 읽어 필터·정렬 메뉴 구성
    • 반복 항목인 TodoItemRow는 기존대로 값만 전달
    • 분리 후 부모 body가 읽는 상태는 alert, fullScreenCover로 한정
    • selectTodo는 전달만 하는 함수라 제거하고 onSelectTodo를 직접 호출
  • TodoEditorView
    • EditorInspector: 기존 .inspector 클로저 안의 Group·switch, inspectorContent, isInspectorPresented를 읽는 인스펙터 내용을 store를 전달받는 private View로 분리, 저장 클로저 없이 .upsertTodo를 직접 전송
    • ToolBar: movesActionsToInspector를 부모에서 제거하고 isWideLayout을 전달받아 store.isInspectorPresented와 함께 showsActions를 직접 계산
    • ContentView: editorHeaderHeight와 safeAreaInsets를 읽어 minimumHeight를 직접 계산하고 GeometryReader의 높이만 전달받음
    • isWideLayout은 인스펙터 컬럼 안에서 horizontalSizeClass가 달라질 수 있어 부모에서 계산해 전달
    • TitleField, ModePicker, EditorToolbarActions는 이미 store를 받아 자체 body에서 상태를 읽고 있어 변경 없음
    • onChange(of: store.saveResult)는 성공 콜백을 소유하므로 부모에 유지
  • Tags.swift는 Tag, TagList가 Store가 아닌 값만 받으므로 변경 없음
  • TodoPropertiesView, TodoDetailView는 이슈가 지정한 파일이 아니므로 범위에서 제외
  • UI 계층, modifier 순서, 탐색 경로와 Store 소유권, 동작은 기존과 동일
  • State, Action, SideEffect, 모듈 의존성, 공개 API 변경 없음

📸 영상 / 이미지 (Optional)

Instruments 측정 (View Body)

  • 조건: Release 최적화(Staging 구성) 빌드, iPhone 18 Pro 시뮬레이터(iOS 27.0), View Body (Legacy), 변경 전후 각 5회 교차 측정 후 중앙값 비교, 괄호는 5회 측정 범위
  • 시나리오: 목록과 편집기 시나리오를 이어서 실행
    • 목록: 홈에서 이슈 목록 진입 후 검색 열기 ↔ 취소 10회
    • 편집기: 목록에서 +로 편집기 진입 후 미리보기 ↔ 작성 전환 10회, 닫기
  • 로그인된 계정의 실제 데이터(이슈 4건) 기준이며 검색어 입력, 필터·정렬 변경, 인스펙터 열기, 스크롤은 측정 대상에서 제외

목록 화면 (검색 열기 ↔ 취소 10회)

대상 변경 전 횟수 변경 전 시간 변경 후 횟수 변경 후 시간
TodoListView (아래 4개 영역 포함) 75회 37.16ms (36.14 ~ 37.54) 3회 8.65ms (8.28 ~ 9.79)
TodoListContent - - 32회 3.24ms (2.87 ~ 3.71)
TodoListTopBar - - 23회 1.92ms (1.86 ~ 1.95)
TodoListSearchBar - - 10회 1.05ms (1.01 ~ 1.11)
TodoListFilterHeader - - 21회 5.93ms (5.85 ~ 6.21)
합계 75회 37.16ms (36.14 ~ 37.54) 89회 20.92ms (20.42 ~ 21.51)
ItemActionButton 761회 1.37ms (1.35 ~ 1.39) 129회 0.35ms (0.31 ~ 0.44)
TodoItemRow 44회 0.97ms (0.91 ~ 1.00) 40회 0.88ms (0.84 ~ 1.20)
  • 변경 전에는 todoListContent, topBar, searchBar, filterHeader가 TodoListView의 계산 프로퍼티로 부모 body 안에서 평가되어 별도 측정값이 없고, 변경 전 TodoListView 값에 모두 포함
  • TodoListView body 평가 횟수가 75회에서 3회로 감소
  • 분리한 View가 추가로 평가되어 평가 횟수 합은 늘었으나, 한 번의 평가 비용이 작아 시간 합계는 감소
  • 반복 항목 하위 View(ItemActionButton)의 평가 횟수 감소
  • TodoItemRow는 측정 범위가 겹쳐 차이로 보지 않음

편집기 화면 (미리보기 ↔ 작성 전환 10회, 닫기)

대상 변경 전 횟수 변경 전 시간 변경 후 횟수 변경 후 시간
TodoEditorView (.inspector 클로저 포함) 41회 4.27ms (3.86 ~ 5.76) 36회 3.25ms (3.21 ~ 3.52)
EditorInspector - - 2회 0.05ms (0.05 ~ 0.08)
합계 41회 4.27ms (3.86 ~ 5.76) 38회 3.33ms (3.29 ~ 3.58)
ToolBar 23회 1.64ms (1.32 ~ 2.27) 22회 1.84ms (1.76 ~ 2.09)
EditorToolbarActions 23회 1.15ms (0.89 ~ 1.47) 22회 1.26ms (1.15 ~ 1.85)
  • 변경 전에는 .inspector 클로저가 TodoEditorView의 body 안에서 평가되어 별도 측정값이 없고, 변경 전 TodoEditorView 값에 포함
  • ToolBar, EditorToolbarActions는 측정 범위가 겹쳐 차이로 보지 않음
  • TodoEditorView는 부모 body가 saveResult, isInspectorPresented, 알림 상태를 계속 읽는 구조
  • 편집기 쪽은 일관된 개선으로 보지 않음
  • ContentView, TodoPropertiesView, ModePicker, TitleField는 이번 측정 대상에서 제외

@opficdev opficdev self-assigned this Oct 28, 2026
@opficdev
opficdev merged commit 9f8b530 into develop Oct 28, 2026
9 checks passed
@opficdev
opficdev deleted the refactor/#884 branch October 28, 2026 16:50
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.

PresentationShared의 View 구성 요소와 렌더링 입력을 분리한다

1 participant