fix(WRP-1402): 디자인 시스템 렌더링 최적화 — analytic 그림자 + Switch·Menu jank 제거#519
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Walkthrough
ChangesShadow 헬퍼 추출 및 컴포넌트 적용
Control 커스텀 캡슐 스위치 구현
기타 변경
추정 코드 리뷰 노력🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
80c0a86 to
fc31f89
Compare
da016e2 to
04f422d
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
Sources/Montage/1 Components/3 Selection And Input/Control.swift (1)
80-84: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win움직이는 thumb에는
View.shadow()대신 analytic shadow를 쓰는 편이 좋겠습니다.이 thumb는 토글할 때마다 애니메이션되는 요소인데, 여기만 다시 view-level shadow를 쓰면 이번 PR의 오프스크린 렌더링 제거 목적을 일부 되돌릴 수 있습니다. 가능하면 새로 추가된
ShapeStyle.shadow(_:)쪽으로 맞춰 주세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Montage/1` Components/3 Selection And Input/Control.swift around lines 80 - 84, The switchThumb view is using a view-level shadow, which can reintroduce offscreen rendering for this animated thumb. Update the switchThumb implementation in Control.swift to use the new ShapeStyle.shadow(_) analytic shadow on the Capsule fill instead of View.shadow(), keeping the same visual styling while matching the rest of the PR.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@documentation/utilities/ios-extensions/swiftuicore.md`:
- Around line 20-31: `ShapeStyle.shadow` 문서 설명이 손상되어 핵심 문구와 Discussion 내용이
빠졌습니다. `ShapeStyle.shadow(level:)` DocC 블록을 `Sources/Montage/1 Components/9
Utilities/Shadow.swift`의 원문과 맞게 복원하고, 반환 설명과 Discussion의 GPU 합성 비용/오프스크린 회피 문구가
빠지지 않도록 다시 생성하거나 해당 문단을 보정하세요.
In `@documentation/utilities/ios-utility-components/shadow.md`:
- Around line 77-88: The `ShapeStyle.shadow` documentation text is malformed and
missing part of the intended wording. Regenerate or manually correct the DocC
content for `ShapeStyle.shadow` so the opening sentence is complete and
grammatical, and restore the missing Discussion sentence fragment to match the
source documentation; use the `ShapeStyle.shadow` section and its
`Discussion`/`Return Value` content as the source of truth.
In `@Sources/Montage/1` Components/3 Selection And Input/Select.swift:
- Around line 396-410: The Select background is applying the same shadow twice,
once in this background block and again in the higher-level RoundedRectangle
used by the Select container. Remove the redundant .shadow(...) from the
duplicated layer so only one shadow is applied, keeping the remaining shadow on
the appropriate RoundedRectangle path in Select.swift.
---
Nitpick comments:
In `@Sources/Montage/1` Components/3 Selection And Input/Control.swift:
- Around line 80-84: The switchThumb view is using a view-level shadow, which
can reintroduce offscreen rendering for this animated thumb. Update the
switchThumb implementation in Control.swift to use the new ShapeStyle.shadow(_)
analytic shadow on the Capsule fill instead of View.shadow(), keeping the same
visual styling while matching the rest of the PR.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: b42b24bf-a20a-4ade-a3e7-df5de82f9dca
📒 Files selected for processing (11)
Sources/Blueprint/Sources/Utilities/PreviewOption.swiftSources/Montage/1 Components/3 Selection And Input/Control.swiftSources/Montage/1 Components/3 Selection And Input/FramedStyle.swiftSources/Montage/1 Components/3 Selection And Input/SegmentedControl.swiftSources/Montage/1 Components/3 Selection And Input/Select.swiftSources/Montage/1 Components/3 Selection And Input/TextArea.swiftSources/Montage/1 Components/3 Selection And Input/TextField.swiftSources/Montage/1 Components/9 Utilities/Shadow.swiftTHIRD_PARTY_LICENSES.mddocumentation/utilities/ios-extensions/swiftuicore.mddocumentation/utilities/ios-utility-components/shadow.md
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@THIRD_PARTY_LICENSES.md`:
- Around line 22-27: The NOTICE block contains an HTTP error string instead of
valid license notice text, so update the THIRD_PARTY_LICENSES.md NOTICE section
to restore the actual upstream NOTICE content or remove the placeholder
entirely. Keep the change focused on the NOTICE entry itself and ensure the
documented third-party notice text is accurate and compliant.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 83ad4954-7c1d-49f2-b58f-f4928ff12758
📒 Files selected for processing (11)
Sources/Blueprint/Sources/Utilities/PreviewOption.swiftSources/Montage/1 Components/3 Selection And Input/Control.swiftSources/Montage/1 Components/3 Selection And Input/FramedStyle.swiftSources/Montage/1 Components/3 Selection And Input/SegmentedControl.swiftSources/Montage/1 Components/3 Selection And Input/Select.swiftSources/Montage/1 Components/3 Selection And Input/TextArea.swiftSources/Montage/1 Components/3 Selection And Input/TextField.swiftSources/Montage/1 Components/9 Utilities/Shadow.swiftTHIRD_PARTY_LICENSES.mddocumentation/utilities/ios-extensions/swiftuicore.mddocumentation/utilities/ios-utility-components/shadow.md
🚧 Files skipped from review as they are similar to previous changes (8)
- Sources/Montage/1 Components/3 Selection And Input/SegmentedControl.swift
- Sources/Montage/1 Components/3 Selection And Input/TextArea.swift
- Sources/Montage/1 Components/3 Selection And Input/FramedStyle.swift
- Sources/Montage/1 Components/3 Selection And Input/TextField.swift
- Sources/Blueprint/Sources/Utilities/PreviewOption.swift
- Sources/Montage/1 Components/3 Selection And Input/Select.swift
- Sources/Montage/1 Components/3 Selection And Input/Control.swift
- Sources/Montage/1 Components/9 Utilities/Shadow.swift
62af813 to
82951ca
Compare
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KB2eZUrUb5uKoUExoX9Fs7
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KB2eZUrUb5uKoUExoX9Fs7
…더링 제거 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KB2eZUrUb5uKoUExoX9Fs7
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KB2eZUrUb5uKoUExoX9Fs7
네이티브 Toggle/UISwitch는 커스텀 tint(.tint·onTintColor)를 지정하는 순간 iOS 26 Liquid Glass 최적화 경로를 벗어나 on/off 애니메이션에서 프레임 드랍이 발생한다. 트랙(Capsule)·thumb(Capsule)을 직접 그려 그 경로를 피한다. 트랙색은 기존 backgroundColor를 그대로 쓰고, 비활성-꺼짐은 .clear(네이티브 색 노출용)이던 것을 ZStack 하위 quaternaryLabel 캡슐로 대체해 반투명 트랙을 유지한다. 접근성은 accessibilityRepresentation의 Toggle로 보존한다. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KB2eZUrUb5uKoUExoX9Fs7
선택값(menuLabel)이 폭이 다른 문자열로 바뀌면 Menu 버튼이 리사이즈되며 행이 reflow돼 프레임 드랍이 생긴다. 라벨을 maxWidth: .infinity로 채워 버튼 프레임을 고정한다. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KB2eZUrUb5uKoUExoX9Fs7
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KB2eZUrUb5uKoUExoX9Fs7
tryFetch가 응답 본문 문자열에만 의존해, HTTP 오류 응답(레이트리밋 안내·에러 페이지 등 '404: Not Found'가 아닌 본문)을 라이선스 텍스트로 오인하던 문제를 수정. - fetch: 비-2xx 응답은 즉시 null 반환 - curl 폴백: -f로 HTTP >=400을 비0 종료로 처리 이로 인해 실제 태그(v1.0.0)보다 먼저 시도되는 잘못된 ref 후보(예: 1.0.0/LICENSE.md)의 일시적 비정상 응답을 채택해 pretendard-ios 라이선스가 Unknown으로 퇴화하던 현상을 방지. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D8gTT3K3Hci759WS9qMf8r
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YaNt4jzRXy4fxXfwZCkiC3
main의 생성기 수정(3785836·f13f69a65)을 체리픽해, NOTICE 페치 실패 시 에러 본문(400: Invalid request)을 기록하지 않고 블록을 생략한다. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KB2eZUrUb5uKoUExoX9Fs7
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D8gTT3K3Hci759WS9qMf8r # Conflicts: # Sources/Blueprint/Blueprint.xcodeproj/project.pbxproj
Refs: WRP-1402
6fd4c84 to
57326af
Compare
Refs: WRP-1402
개요
WRP-1402 디자인 시스템 렌더링 최적화. Blueprint 인터랙션 프레임 드랍(jank)의 원인을 제거하면서 시각적 외형은 유지한다.
배경
Blueprint 전반의 인터랙션(스위치 토글, Menu 라벨 갱신, 스크롤)에서 프레임 드랍이 관측됐다. 시뮬레이터·실기기(iOS 26) Release 모두 재현. 근본 메커니즘은 GPU 합성(렌더 서버) 부하 — 오프스크린 렌더링, 레이어 블렌딩, 그리고 iOS 26 네이티브 컨트롤의 fast-path 이탈이다. 앱-attach Time Profiler에는 잡히지 않아(렌더 서버는 별도 프로세스) CPU/색상 최적화로는 체감이 바뀌지 않았다.
변경 사항
1. Analytic 그림자 (오프스크린 렌더링 제거)
ShapeStyle.shadow(_:)API 추가 —Shape.fill에 적용하면 그림자가 지오메트리로부터 직접 그려져 오프스크린 패스가 발생하지 않는다. 기존View.shadow(_:)는 임의 콘텐츠 실루엣을 알기 위해 오프스크린을 유발(특히clipShape/머티리얼과 함께).TextField·Select표면,SegmentedControl·TextArea인디케이터,FramedStyle.2. Switch — tint 기인 on/off jank 제거
Toggle/UISwitch는 커스텀 tint 색(.tint또는onTintColor)을 지정하는 순간 iOS 26 Liquid Glass 최적화 경로를 벗어나 fallback 렌더로 떨어져, on/off 애니메이션에서 프레임 드랍이 발생한다. (단일변수 격리로 확인: transform 무관, 브랜드색 무관,onTintColor지정 한 줄만 빼면 사라짐)Capsule(트랙) +Capsule(thumb)로 직접 그려 해당 경로를 회피. 트랙색은 기존backgroundColor를 그대로 재사용하고, 비활성-꺼짐 상태(.clear)는quaternaryLabel캡슐로 대체해 반투명 트랙을 유지. thumb는 iOS 26 디자인에 맞춘 가로 캡슐 형태. 접근성은accessibilityRepresentation의Toggle로 보존.3. MenuOptionRow — 라벨 reflow jank 완화 (Blueprint)
Menu라벨이 폭이 다른 문자열로 바뀌면 버튼 리사이즈 → 행 reflow로 프레임 드랍. 라벨을maxWidth: .infinity로 채워 프레임을 고정.검증
🤖 Generated with Claude Code