"한 플랫폼의 렌더링을 아는 것과, 모든 UI가 같은 파이프라인의 다른 구현임을 아는 것은 다르다"
"Browser·Compose·SwiftUI·Flutter는 서로 다른 언어처럼 보이지만, 빌드 → 레이아웃 → 페인트 → 합성 → GPU라는 같은 다섯 단계를 다르게 구현한 결과다"
선언적 UI 트리가 화면 픽셀이 되는 길을 4개 UI 플랫폼과 그 아래 GPU 바닥까지 같은 파이프라인 위에 나란히 놓고 단계별로 비교합니다
렌더링 자료는 플랫폼별로 따로 흩어져 있습니다. 하지만 대부분은 "내 플랫폼은 이렇게 그린다" 에서 멈춥니다.
| 일반 자료 | 이 레포 |
|---|---|
| "브라우저는 Layout → Paint → Composite를 거친다" | Compose·SwiftUI·Flutter도 같은 다섯 단계(빌드→레이아웃→페인트→합성→GPU)를 거친다는 것을 한 표에 매핑한다 |
| "Flutter는 60fps를 위해 자체 엔진을 쓴다" | Browser·Compose·SwiftUI는 플랫폼 합성, Flutter만 자체 렌더 — 같은 "크로스 플랫폼"이라도 RN과 정반대 접근인 이유 |
| "transform 애니메이션은 GPU가 처리해서 빠르다" | 같은 원리(레이아웃·페인트 건너뛰고 합성만)가 4플랫폼 모두에서 작동함을 나란히 확인 |
| "리스트 항목 하나만 바꾸면 효율적이다" | React Fiber·Compose Slot Table·SwiftUI AttributeGraph·Flutter Element diff가 같은 문제를 4가지로 푼다 |
| "jank는 16.6ms를 넘기는 것" | 4플랫폼이 공통 60fps 예산을 공유하며 jank의 원인 단계(빌드/레이아웃/페인트)도 공통이다 |
| "Skia가 그리고 GPU가 합성한다" | 사각형·텍스트·이미지가 결국 삼각형+텍스처+셰이더로 수렴하는 경로를 4플랫폼별로 추적 |
| 한 플랫폼만 설명 | 같은 화면을 4플랫폼으로 구현해 프레임 비용을 측정 + 단계 매핑 표 |
선행 학습 권장: 각 플랫폼 내부는 선행 레포에서 깊이 다룹니다. 이 레포는 그것들을 나란히 놓는 종합편입니다 → browser-rendering-deep-dive · jetpack-compose-internals-deep-dive · swiftui-internals-deep-dive · flutter-deep-dive · gpu-graphics-deep-dive
각 챕터의 첫 문서부터 바로 학습을 시작하세요!
💡 각 섹션을 클릭하면 상세 문서 목록이 펼쳐집니다
핵심 질문: 4개 UI 플랫폼이 정말 같은 파이프라인의 다른 구현인가?
공통 다섯 단계, 선언적 UI의 수렴, 두 갈래, 60fps 예산, 비교 프레임 (5개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 공통 다섯 단계 | 선언/빌드 → 측정/레이아웃 → 페인트 → 합성 → GPU 래스터 — 이 다섯 단계가 모든 UI에 공통으로 존재함을 4플랫폼 단면으로 보여준다 |
| 02. 선언적 UI의 수렴 | React·Compose·SwiftUI·Flutter가 모두 UI = f(state)로 같은 모델로 수렴한 역사, 그래서 비교가 의미 있는 이유 |
| 03. 두 갈래 — 플랫폼 합성 vs 자체 렌더 | Browser·Compose·SwiftUI(플랫폼 위젯 합성) vs Flutter(엔진이 모든 픽셀) — 같은 파이프라인의 철학적 분기 |
| 04. 60fps 예산 | 16.6ms를 4플랫폼이 공유하는 공통 통화, jank의 정의가 플랫폼 독립적인 이유 |
| 05. 비교 프레임 | 단계 매핑·네이티브 통합·제어·일관성 — 이 레포 전체에서 사용할 네 가지 평가 축 |
핵심 질문: "변경된 부분만 갱신"이라는 같은 문제를 4플랫폼이 어떻게 다르게 푸는가?
공통 문제, Fiber·Slot Table·AttributeGraph·Element, 나란히 비교 (6개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 공통 문제 — 선언적 트리의 최소 갱신 | "전체 다시 그리지 말고 바뀐 곳만"이 모든 선언적 UI의 공통 과제임을 정리, 왜 이 문제가 4가지로 풀렸는지 |
| 02. React Fiber — VDOM diff + 재조정 | VDOM 두 트리 비교, 키 기반 재배치, 우선순위 스케줄링 — browser-rendering 레포의 결론을 비교 관점에서 재해석 |
| 03. Compose — Slot Table 위치 기억 | gap buffer 기반 슬롯에 호출 위치별 상태를 저장, 리컴포지션 시 변경 감지 — jetpack-compose 레포로 깊이 위임 |
| 04. SwiftUI — AttributeGraph 의존성 추적 | 뷰의 입출력을 의존성 그래프로 모델링, 변경된 입력에 영향받는 노드만 무효화 — swiftui 레포 연결 |
| 05. Flutter — Element 트리 diff + RenderObject 재사용 | Widget(불변 청사진) → Element(상태) → RenderObject(렌더 단위)의 3단 분리가 만드는 갱신 효율 — flutter 레포 연결 |
| 06. 나란히 — "리스트 1항목 변경"을 4플랫폼이 어떻게 | 같은 시나리오를 4가지 메커니즘이 어떻게 좁히는지, 변경 범위 시각화 도구를 각 플랫폼에서 켜고 직접 비교 |
핵심 질문: 같은 "박스를 배치하는 문제"를 단일 패스 vs 다중 패스로 푸는 트레이드오프는 무엇인가?
레이아웃 문제, Flexbox/Grid, 단일 패스, 크기 협상, 비교 (5개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 레이아웃 문제 | 제약 전달·크기 결정·배치라는 공통 3단계, 모든 레이아웃 시스템이 이 문제를 푸는 변종임을 정리 |
| 02. 웹 레이아웃 — Flexbox/Grid·다중 패스 | CSS 박스 모델, intrinsic sizing, 다중 패스가 표현력은 높지만 비용은 큰 이유 — css-engine-layout 레포 연결 |
| 03. Compose/Flutter — 단일 패스 측정 | 제약 ↓ 크기 ↑ 단방향 흐름이 만드는 O(n) 보장, 웹과의 정량 비교 |
| 04. SwiftUI — 크기 협상 | 부모가 제안하고 자식이 선택하는 비대칭 협상 모델, Compose의 단일 패스와는 또 다른 변종 |
| 05. 나란히 — 단일 vs 다중 패스의 비용·표현력 | 같은 레이아웃 시나리오의 프레임 시간 측정, 어느 쪽이 어떤 상황에서 이기는지 표로 정리 |
핵심 질문: "transform 애니메이션은 왜 모든 플랫폼에서 싸게 처리되는가?"
페인트, 합성, 레이어 승격, Core Animation, Skia/Impeller, 비교 (6개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 페인트 — 그리기 명령 생성 | display list / paint record가 모든 플랫폼의 공통 중간 표현, 페인트 순서(stacking)가 만드는 결과 |
| 02. 합성 — 레이어를 GPU에서 합치기 | 합성 단계가 메인 스레드 없이 가능한 작업의 범위, 4플랫폼이 동일 원리를 어떻게 노출하는지 |
| 03. Browser 레이어 — 승격과 합성 | will-change·transform·opacity가 레이어 승격을 유발하고 메인 스레드를 건너뛰는 메커니즘 — browser 레포 연결 |
| 04. iOS Core Animation — 별도 Render Server | 레이어 트리가 앱 프로세스 밖의 Render Server로 넘어가 60fps를 보장하는 구조 — uikit-core-animation 레포 연결 |
| 05. Compose/Flutter 합성 — Skia/Impeller·repaint boundary | 자체 합성기가 repaint boundary로 부분 무효화를 처리, 플랫폼 합성기와의 직접 비교 |
| 06. 나란히 — "transform 애니메이션" | 같은 transform 애니메이션이 4플랫폼에서 레이아웃/페인트를 건너뛰는지 DevTools로 확인 |
핵심 질문: Flutter는 왜 네이티브 뷰를 안 쓰는가? RN은 왜 정반대를 택했는가?
두 철학, 플랫폼 합성, 자체 렌더, 트레이드오프, RN vs Flutter (5개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 두 철학 | "플랫폼 위젯을 합성한다" vs "자체 캔버스에 직접 그린다" — 같은 크로스 플랫폼 목표를 정반대로 푸는 두 갈래 |
| 02. 플랫폼 합성 — Browser·Compose·SwiftUI·RN | 네이티브 위젯을 제어해 플랫폼 룩앤필을 그대로 얻는 접근, 플랫폼 일관성의 이득과 한계 |
| 03. 자체 렌더 — Flutter | 엔진이 모든 픽셀을 직접 그려 크로스 플랫폼 일관성과 완전한 제어를 얻는 접근 — flutter 레포 연결 |
| 04. 트레이드오프 | 플랫폼 일관성 vs 크로스 일관성, 룩앤필 vs 제어, 업데이트 지연 vs 자유도 — 네 축 비교 표 |
| 05. RN vs Flutter | 같은 "크로스 플랫폼"인데 RN은 네이티브 뷰 제어, Flutter는 자체 렌더 — 같은 목표를 정반대로 (react-native 레포 연결) |
핵심 질문: 사각형·텍스트·이미지가 결국 삼각형+텍스처+셰이더가 되는 경로는?
공통 종착점, 2D도 GPU, 렌더 엔진, 글리프 아틀라스, 셰이더, 비교 (6개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 공통 종착점 | 4플랫폼이 어떤 추상화를 거치든 마지막은 GPU 파이프라인 — 이 레포가 gpu 레포로 수렴하는 이유 |
| 02. 2D도 GPU | 사각형·텍스트·이미지가 삼각형 쿼드 + 텍스처 + 셰이더로 표현되는 원리 — gpu 레포 연결 |
| 03. 렌더 엔진 | Skia(Browser·Flutter)·Core Animation(iOS)·각 엔진의 GPU 활용 전략 나란히 |
| 04. 텍스트 렌더링 — 글리프 아틀라스 | 글리프를 텍스처 아틀라스에 캐시하는 모든 플랫폼 공통 패턴, 텍스트가 GPU 친화적이 되는 변환 |
| 05. 셰이더·합성 | 블렌딩·마스킹·블러가 프래그먼트 셰이더에서 수행되는 GPU 합성의 마지막 단계 |
| 06. 나란히 — 같은 화면의 GPU 도달 경로 | "스크롤 + 이미지 + 텍스트" 화면이 4플랫폼에서 각각 어떤 GPU 호출로 끝나는지 추적 |
핵심 질문: 새로운 UI 프레임워크를 만나도 이 파이프라인으로 분석할 수 있는가?
jank의 공통 원인, 플랫폼별 도구, 동일 화면 비교, 트레이드오프 표, 종합 (5개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. jank의 공통 원인 | 프레임 예산 초과가 어느 단계(빌드/레이아웃/페인트/합성)에서 일어나는지 4플랫폼 공통으로 분류 |
| 02. 플랫폼별 jank 도구 | Chrome DevTools·Layout Inspector·Instruments·Flutter DevTools를 같은 단계에서 무엇을 볼지 매핑 |
| 03. 같은 화면 비교 | 동일 UI(스크롤 리스트 + 애니메이션)를 4플랫폼 코드 스니펫으로 나란히 구현 + 프레임 비용 측정 |
| 04. 트레이드오프 종합 | 단계 매핑·네이티브 통합·제어·일관성을 4×4 매트릭스로 정리, 의사결정 가이드 |
| 05. 종합 — 렌더링 지형도 | 새 프레임워크가 등장해도 이 다섯 단계로 분해해 분석할 수 있다는 결론, 다음 학습 경로 |
🟢 "왜 transform이 모든 플랫폼에서 싸게 처리되는가" 한 줄로 답하고 싶다 (1주)
Ch1-01 공통 다섯 단계
Ch1-04 60fps 예산
Ch4-01 페인트
Ch4-02 합성
Ch4-06 나란히 — transform 애니메이션
→ "레이아웃·페인트를 건너뛰고 GPU 합성만 한다 — 4플랫폼 모두 동일 원리"
🔵 4플랫폼 렌더링을 같은 파이프라인 위에서 이해하고 싶은 개발자 (7주)
Week 1 Chapter 1 전체 — 공통 파이프라인의 정의
Week 2 Chapter 2 전체 — 빌드/재조정 (Fiber·Slot·AG·Element)
Week 3 Chapter 3 전체 — 레이아웃 (단일 vs 다중 패스)
Week 4 Chapter 4 전체 — 페인트와 합성
Week 5 Chapter 5 전체 — 네이티브 뷰 vs 자체 렌더
Week 6 Chapter 6 전체 — GPU 수렴
Week 7 Chapter 7 전체 — 성능·종합·의사결정
🔴 "Flutter 도입을 평가해야 한다 / RN과 무엇이 다른가" 의사결정자 (집중 코스)
핵심 경로 (트레이드오프 중심)
Step 1 Ch1-03 플랫폼 합성 vs 자체 렌더 갈래
Step 2 Ch5-01 두 철학 — 같은 목표를 정반대로
Step 3 Ch5-02~03 플랫폼 합성·자체 렌더 각각의 메커니즘
Step 4 Ch5-04 네 축 트레이드오프 표
Step 5 Ch5-05 RN vs Flutter — 같은 크로스 플랫폼의 분기
Step 6 Ch7-03 같은 화면 4구현 비교 (실측)
Step 7 Ch7-04 의사결정 매트릭스
🟡 "jank를 잡는데 도구가 플랫폼마다 달라서 헷갈린다" 성능 엔지니어 (집중 코스)
Step 1 Ch1-04 60fps 공통 예산
Step 2 Ch7-01 jank의 공통 원인 (단계별 분류)
Step 3 Ch7-02 플랫폼별 도구를 같은 단계로 매핑
Step 4 Ch4-01~02 페인트·합성을 깊이 (가장 흔한 jank 단계)
Step 5 Ch2-06 "1항목 변경" 비교 (재조정 단계 jank)
Step 6 Ch7-03 같은 화면 4구현 프레임 측정
rendering-pipelines-compared/
├── README.md
├── LICENSE
├── .gitignore
│
├── common-pipeline/ Ch1. 공통 파이프라인 (5)
│ ├── 01-five-stages.md
│ ├── 02-declarative-convergence.md
│ ├── 03-two-branches.md
│ ├── 04-60fps-budget.md
│ └── 05-comparison-frame.md
│
├── build-and-reconciliation/ Ch2. 빌드/재조정 (6)
│ ├── 01-common-problem.md
│ ├── 02-react-fiber.md
│ ├── 03-compose-slot-table.md
│ ├── 04-swiftui-attributegraph.md
│ ├── 05-flutter-element.md
│ └── 06-side-by-side.md
│
├── layout/ Ch3. 레이아웃 (5)
│ ├── 01-layout-problem.md
│ ├── 02-web-flexbox-grid.md
│ ├── 03-single-pass.md
│ ├── 04-swiftui-negotiation.md
│ └── 05-side-by-side.md
│
├── paint-and-composite/ Ch4. 페인트와 합성 (6)
│ ├── 01-paint.md
│ ├── 02-composite.md
│ ├── 03-browser-layers.md
│ ├── 04-core-animation.md
│ ├── 05-compose-flutter.md
│ └── 06-side-by-side.md
│
├── native-vs-self-render/ Ch5. 네이티브 뷰 vs 자체 렌더 (5)
│ ├── 01-two-philosophies.md
│ ├── 02-platform-composition.md
│ ├── 03-self-render-flutter.md
│ ├── 04-tradeoffs.md
│ └── 05-rn-vs-flutter.md
│
├── gpu-bottom/ Ch6. GPU 바닥 (6)
│ ├── 01-common-destination.md
│ ├── 02-2d-is-gpu.md
│ ├── 03-render-engines.md
│ ├── 04-text-glyph-atlas.md
│ ├── 05-shader-composite.md
│ └── 06-side-by-side.md
│
├── performance-and-synthesis/ Ch7. 성능과 종합 (5)
│ ├── 01-jank-common-causes.md
│ ├── 02-jank-tools.md
│ ├── 03-same-screen-comparison.md
│ ├── 04-tradeoffs-summary.md
│ └── 05-rendering-landscape.md
총 38개 문서
💡 동일 화면 4구현 비교는 Ch7-03(같은 화면 비교)에 4플랫폼 코드 스니펫이 모두 포함되어 있습니다. 시나리오(스크롤 리스트 + transform 애니메이션 + 텍스트 카드 200개)를 그대로 가져다 DevTools로 측정해보세요.
모든 문서는 동일한 구조로 작성됩니다. 비교가 핵심이라 🔬·📊에서 항상 여러 플랫폼을 나란히 둡니다.
| 섹션 | 설명 |
|---|---|
| 🎯 핵심 질문 | 이 문서를 읽고 나면 답할 수 있는 질문 |
| 🔍 왜 이게 존재하는가 | 공통 문제 상황과 각 플랫폼이 그 문제를 마주한 배경 |
| 😱 흔한 오해 | "Flutter는 네이티브 뷰를 쓴다" 같은 플랫폼 간 오해 |
| ✨ 올바른 이해 | 공통 파이프라인 위에 매핑한 정확한 그림 |
| 🔬 내부 동작 원리 | 다이어그램으로 최소 2~3 플랫폼을 같은 단계에서 비교 |
| 💻 실전 실험 | 같은 화면을 여러 플랫폼으로 구현하고 DevTools로 단계별 추적 |
| 📊 측정 | 프레임 시간·갱신 범위·메모리를 4플랫폼 동일 조건에서 비교 |
| 🤔 트레이드오프 | 네 가지 평가 축(단계 매핑·네이티브 통합·제어·일관성)에서 정리 |
| 📌 핵심 정리 | 한 화면 요약 (공통 파이프라인 + 플랫폼별 변종) |
| 🤔 생각해볼 문제 | 다른 플랫폼에 같은 분석을 적용하는 응용 질문 + 해설 |
멀티 플랫폼. 같은 화면을 4개로 구현해 DevTools로 단계별 비용을 비교합니다.
# 검증 시나리오 — "스크롤 리스트 + transform 애니메이션 + 텍스트가 많은 카드"
# Ch7-03 문서에 4구현 코드 스니펫이 모두 포함되어 있음
# [1] Web (Browser)
# Chrome DevTools → Performance / Rendering
# Paint flashing · Layer borders 로 합성 단계 시각화
# Layout/Recalculate Style/Paint/Composite 시간 분리 측정
# [2] Android (Jetpack Compose)
# Layout Inspector → 리컴포지션 카운트
# Macrobenchmark → FrameTiming (frameDurationCpuMs · frameOverrunMs)
# Compose Compiler Metrics → @Stable / skippable 통계
# [3] iOS (SwiftUI)
# Instruments → Core Animation FPS
# _printChanges() → 어떤 입력이 뷰를 무효화시켰는가
# Time Profiler → 메인 스레드 핫스팟
# [4] Flutter
# Flutter DevTools → Performance
# Repaint Rainbow → 다시 그리는 영역 시각화
# UI 스레드 vs Raster 스레드 시간 분리
# 비교 측정 — 모든 플랫폼에서 같은 지표를 뽑는다
# · transform 애니메이션 시 레이아웃/페인트가 건너뛰어지는가? (합성 only?)
# · 리스트 1항목 변경 시 갱신 범위 (몇 개 노드가 다시 평가/그려지는가)
# · 프레임 시간 분포 (p50·p99·jank rate, 16.6ms 예산 대비)
# · 텍스트 100개 카드의 페인트·GPU 업로드 비용⬆️ 선행 (이 비교의 입력)
browser-rendering-deep-dive → Composite·Layer·Paint
jetpack-compose-internals-deep-dive → Slot Table·Recomposer·LayoutNode
swiftui-internals-deep-dive → AttributeGraph·ViewGraph
uikit-core-animation-deep-dive → 레이어 트리·Render Server
flutter-deep-dive → Widget→Element→RenderObject·Skia/Impeller
gpu-graphics-deep-dive → 삼각형·텍스처·셰이더 (공통 바닥)
🤝 시너지
react-native-deep-dive → 네이티브 뷰 제어 방식 (Flutter와 대조)
css-engine-layout-deep-dive → 웹 레이아웃 알고리즘 깊이
computer-architecture-deep-dive → GPU 메모리·대역폭의 하드웨어 한계
🧬 본질 (이 레포의 정체성)
rendering-pipelines-compared 자체가 5개 선행 레포의 수렴점.
4개 UI 플랫폼 + GPU 바닥을 하나의 파이프라인 프레임으로 묶는다.
- web.dev — Rendering Performance
- Jetpack Compose — Phases of a frame
- SwiftUI — View updates and identity
- Flutter — Inside Flutter / Rendering pipeline
- Skia · Impeller
- Real-Time Rendering — Akenine-Möller et al. (GPU 공통 바닥)
- "How browsers work" — Tali Garsiel
- Apple WWDC, Google I/O, Flutter Forward 렌더링 발표들
⭐️ 도움이 되셨다면 Star를 눌러주세요!
Made with ❤️ by Dev Book Lab
"한 플랫폼 렌더링을 아는 것과, 모든 UI가 공통 파이프라인의 다른 구현임을 아는 것은 다르다"