[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -1,126 +1,160 @@
|
||||
---
|
||||
id: wiki-2026-0508-impeller-engine
|
||||
title: Impeller Engine
|
||||
category: Frontend
|
||||
status: needs_review
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: []
|
||||
aliases: [Impeller, Flutter Impeller, Skia Replacement]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.92
|
||||
tags: [auto-wikified, technical-documentation, frontend]
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [flutter, rendering, gpu, metal, vulkan]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-08
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
tech_stack:
|
||||
language: unspecified
|
||||
framework: unspecified
|
||||
language: dart
|
||||
framework: flutter
|
||||
---
|
||||
|
||||
# Impeller Engine
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
Impeller Engine은 Flutter 프레임워크에서 기존 Skia를 대체하기 위해 도입된 **차세대 자체 렌더링 엔진**입니다. 애플리케이션 빌드 단계에서 셰이더(Shader)를 사전 컴파일하여 런타임에 발생하는 셰이더 컴파일 버벅거림(Jank) 문제를 근본적으로 해결하도록 설계되었습니다. iOS에서는 기본 렌더러로 이미 안정화되었으며 Android에서도 점진적으로 도입되고 있어, 고도화된 애니메이션 환경에서도 일관된 60fps~120fps 성능을 제공하는 모바일 크로스 플랫폼 아키텍처의 핵심 요소입니다.
|
||||
## 매 한 줄
|
||||
> **"매 shader compilation jank 의 제거 — precompiled, predictable"**. Flutter 의 새 rendering engine, Skia 의 replacement. 매 first-frame shader hitch (iOS 특히) 의 근본 해결 — 매 shader 를 build-time 에 precompile 하여 runtime JIT 의 회피.
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
* **도입 배경 및 Skia 대체:** 기존 Flutter의 주요 성능 문제였던 **'셰이더 컴파일 버벅거림(Shader compilation jank)'을 해결하기 위해 개발**되었습니다 [1, 2]. iOS(Flutter 3.10부터) 및 최신 Android 버전에서 기존의 Skia 엔진을 대체하여 기본 그래픽 백엔드로 적용되고 있습니다 [1, 2].
|
||||
* **사전 컴파일 메커니즘:** 새로운 시각적 효과가 화면에 나타날 때 런타임에 셰이더를 컴파일하여 프레임 드롭이 발생하던 기존 방식과 달리, **빌드 과정에서 더 작고 단순하며 최적화된 셰이더 세트를 미리 컴파일(Pre-compiles)**합니다 [2, 3]. 이를 통해 앱 실행 시 첫 프레임부터 부드럽고 예측 가능한 성능을 보장합니다 [3].
|
||||
* **모바일 GPU 최적화:** 현대 모바일 GPU에 최적화된 **테셀레이션(Tessellation) 기반 렌더링 방식을 사용**하여, 복잡한 커스텀 애니메이션과 화면 전환에서도 높은 프레임 레이트(예: 120fps)의 유동적이고 일관된 성능을 유지할 수 있습니다 [2, 3].
|
||||
* **자체 렌더링 아키텍처:** 플랫폼의 네이티브 UI 컴포넌트(예: iOS의 UIKit, Android의 Views)에 의존하거나 호출하지 않고, **자체 렌더링 엔진(Impeller)을 사용하여 화면의 모든 픽셀을 직접 그립니다(Draws every pixel)** [4-6]. 이는 모든 모바일 기기 및 플랫폼에서 픽셀 단위로 일치하는 완벽한 UI 일관성을 제공합니다 [4, 5].
|
||||
## 매 핵심
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
* **앱 크기(App Size) 증가:** Impeller 렌더링 엔진과 Dart 런타임이 앱 패키지에 자체적으로 포함되어야 하므로, 최소한의 기능을 가진 앱이라 하더라도 **기본 APK 크기가 대략 8~12MB 수준으로 증가**합니다. 이는 네이티브 컴포넌트를 사용하여 상대적으로 앱 크기가 작은 React Native(5~8MB)에 비해 큰 편입니다 [7].
|
||||
* **네이티브 플랫폼 표준과의 미묘한 괴리:** 화면의 픽셀을 직접 렌더링하여 높은 커스터마이징과 일관성을 보장하지만, **플랫폼의 기본 네이티브 UI 컴포넌트를 사용하지 않으므로 발생하는 반대 급부**가 있습니다. 스크롤 물리 효과(Scroll physics), 텍스트 선택 동작, 접근성 의미(Accessibility semantics) 등에서 플랫폼 표준과 미묘한 차이가 발생할 수 있으며, OS 업데이트로 인한 새로운 UI 패러다임이 등장할 경우 이를 일일이 커뮤니티가 복제(Replicate)하여 구현해야 합니다 [4, 8].
|
||||
* **플랫폼 간 성숙도 불균형:** iOS에서는 이미 프로덕션 레벨로 안정화되어 기본 렌더러로 강력한 성능을 내고 있지만, **Android 버전에서는 여전히 프리뷰 단계이거나 지속 개선 중인 상태**입니다. 이로 인해 두 플랫폼 간 완전한 렌더링 안정성을 동일하게 보장받기까지는 약간의 시차가 존재합니다 [2, 9].
|
||||
### 매 Skia 의 문제
|
||||
- Skia 의 SkSL shader 는 매 runtime 에 platform 별 (Metal MSL / Vulkan SPIR-V) 로 compile.
|
||||
- 매 first encounter 시 ms-단위 stall — janky animation onset.
|
||||
- iOS 의 특히 심각 (Metal pipeline state object 의 cost).
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
### Related Concepts
|
||||
### 매 Impeller 의 솔루션
|
||||
- **Ahead-of-time shader compilation**: build 시 모든 shader 를 platform IR 로 변환.
|
||||
- **Predictable performance**: runtime 에 매 shader compile 의 X — frame budget 안정.
|
||||
- **Tessellation**: GPU-friendly geometry pipeline (path → triangles 의 CPU offload).
|
||||
- **Backend**: iOS Metal (stable, Flutter 3.10+ default), Android Vulkan (stable, 3.27+ default), macOS Metal.
|
||||
|
||||
#### [관계 유형 A (아키텍처/기반 기술)]
|
||||
- [[Skia]]
|
||||
- 연결 이유: Impeller 이전에 Flutter가 기본으로 사용하던 2D 그래픽 렌더링 엔진입니다 [1, 10].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 기존 엔진의 런타임 셰이더 컴파일로 인한 jank 발생 원리와 Impeller로의 렌더링 아키텍처 교체 당위성을 이해할 수 있습니다 [1, 2].
|
||||
- [[Dart]]
|
||||
- 연결 이유: Flutter 앱과 Impeller 렌더링 엔진을 구동하는 핵심 프로그래밍 언어입니다 [7, 11].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: AOT(Ahead-of-Time) 컴파일 방식을 통해 네이티브 ARM 코드로 변환되는 과정과, 이것이 어떻게 셰이더 사전 컴파일 구조와 시너지를 내어 콜드 스타트 성능을 높이는지 파악할 수 있습니다 [12, 13].
|
||||
### 매 응용
|
||||
1. iOS Flutter 앱 의 매 launch animation jank 제거.
|
||||
2. 매 complex path animation (Lottie, custom painters) 의 안정 frame rate.
|
||||
3. 매 game-like Flutter UI 의 60/120Hz 유지.
|
||||
|
||||
#### [관계 유형 B (비교 대상/경쟁 패턴)]
|
||||
- [[React Native New Architecture]]
|
||||
- 연결 이유: Flutter의 Impeller 엔진 도입 시기와 맞물려 진행된 React Native의 핵심 아키텍처 개편(Fabric, TurboModules, JSI 도입) 모델입니다 [9, 14].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 현대 모바일 개발에서 성능 향상을 위해 '자체 렌더링 엔진 강화(Flutter)'와 '동기적 네이티브 브릿지 전환(React Native)'이라는 상반된 아키텍처적 접근 방식을 비교 분석할 수 있습니다 [15].
|
||||
- [[Shader Compilation Jank]]
|
||||
- 연결 이유: Impeller가 도입된 가장 큰 목적이자 해결하고자 한 핵심 성능 병목 현상입니다 [1, 2].
|
||||
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 모바일 앱에서 새로운 시각적 효과나 복잡한 애니메이션이 처음 화면에 나타날 때 발생하는 프레임 드롭(Frame drop)의 근본적인 메커니즘을 이해할 수 있습니다 [2].
|
||||
## 💻 패턴
|
||||
|
||||
### Deeper Research Questions
|
||||
- Impeller 엔진의 테셀레이션(Tessellation) 기반 렌더링 방식이 기존 Skia 대비 최신 모바일 GPU 구조에서 구체적으로 어떤 하드웨어적 이점을 지니는가?
|
||||
- 빌드 타임에 셰이더를 사전 컴파일(Pre-compiling)하는 아키텍처가 CI/CD 파이프라인의 앱 빌드 소요 시간에 미치는 영향과 최적화 방안은 무엇인가?
|
||||
- Android 환경에서 Impeller 엔진이 iOS만큼 즉각적으로 안정화되지 못하고 프리뷰 상태로 유지된 기술적 및 OS 환경적 제약 사항은 무엇인가?
|
||||
- 자체 렌더링 엔진(Impeller)을 사용할 때 필연적으로 발생하는 네이티브 접근성(Accessibility semantics)의 미묘한 차이를 해결하기 위해 Flutter 내부의 Semantics 시스템은 어떻게 동작하는가?
|
||||
- Impeller를 사용하는 Flutter 앱과 Fabric 렌더러를 사용하는 React Native 앱 간의 메모리 오버헤드 차이는 대규모 엔터프라이즈 환경에서 어떻게 스케일링되는가?
|
||||
|
||||
### Practical Application Contexts
|
||||
- **Implementation:** 매우 복잡한 커스텀 파티클 효과, 3D에 준하는 렌더링, 혹은 복잡한 애니메이션이 요구되는 모바일 앱을 구현할 때, 프레임 드롭 없는 부드러운 UI를 제공하기 위한 렌더링 엔진으로 사용됩니다 [16].
|
||||
- **System Design:** 크로스 플랫폼 프레임워크를 도입할 때, 네이티브 컴포넌트를 재사용하는 대신 **모든 픽셀을 엔진이 직접 그리도록(Draws every pixel)** 설계하여 플랫폼(iOS/Android)에 상관없는 완벽한 브랜드 UI 일관성을 확보하는 아키텍처 결정으로 연결됩니다 [4-6].
|
||||
- **Operation / Maintenance:** 특히 iOS 기기에서 새로운 애니메이션이나 화면 전환 시 최초 실행에서 자주 발생하여 사용자 경험을 훼손했던 '초기 버벅거림' 버그 및 이슈 대응의 유지보수 비용을 크게 줄일 수 있습니다 [2, 7].
|
||||
- **Learning Path:** 현대 크로스 플랫폼 성능 최적화 학습 시, 브릿지 기반 통신 병목을 해결하는 React Native의 방식과 자체 렌더링 엔진의 셰이더를 사전 컴파일하는 Flutter의 방식을 대조하는 훌륭한 교보재로 활용됩니다 [9].
|
||||
- **My Project Relevance:** 브랜드 아이덴티티가 확고하여 네이티브 OS의 기본 UI 규칙보다 커스텀 UI 디자인이 주를 이루는 B2C 애플리케이션을 개발할 경우, Impeller의 도입으로 예측 가능하고 일관된 120fps 애니메이션 렌더링을 계획할 수 있습니다 [2, 17].
|
||||
|
||||
### Adjacent Topics
|
||||
- [[Fabric Renderer]]
|
||||
- 확장 방향: React Native의 새로운 렌더링 시스템인 Fabric이 동기적으로 네이티브 뷰의 크기를 측정하고 렌더링하는 방식과, 자체적으로 화면을 그리는 Impeller의 아키텍처적 차이를 깊이 탐구할 수 있습니다.
|
||||
- [[AOT Compilation (Ahead-of-Time)]]
|
||||
- 확장 방향: Dart 언어의 AOT 컴파일이 어떻게 JIT 컴파일에 비해 앱의 콜드 스타트(Cold start) 시간을 단축시키는지 조사하고, 이것이 셰이더 사전 컴파일과 만나 만들어내는 초기 로딩 속도 최적화 원리를 이해할 수 있습니다.
|
||||
|
||||
---
|
||||
*Last updated: 2026-05-03*
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
|
||||
- **정보 상태:** needs_review
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
|
||||
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
|
||||
- **처리 방식:** UPDATE (자동 정규화)
|
||||
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
|
||||
## 💻 코드 패턴 (Code Patterns)
|
||||
|
||||
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
|
||||
|
||||
```text
|
||||
# TODO
|
||||
### Impeller 활성화 확인 (iOS)
|
||||
```dart
|
||||
// ios/Runner/Info.plist
|
||||
<key>FLTEnableImpeller</key>
|
||||
<true/>
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준 (Decision Criteria)
|
||||
### Custom shader (Impeller-compatible)
|
||||
```glsl
|
||||
// shaders/wave.frag
|
||||
#version 460 core
|
||||
#include <flutter/runtime_effect.glsl>
|
||||
|
||||
**선택 A를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
uniform vec2 uSize;
|
||||
uniform float uTime;
|
||||
out vec4 fragColor;
|
||||
|
||||
**선택 B를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
void main() {
|
||||
vec2 uv = FlutterFragCoord().xy / uSize;
|
||||
float wave = sin(uv.x * 10.0 + uTime) * 0.5 + 0.5;
|
||||
fragColor = vec4(wave, uv.y, 1.0 - wave, 1.0);
|
||||
}
|
||||
```
|
||||
|
||||
**기본값:**
|
||||
> *(TODO)*
|
||||
```yaml
|
||||
# pubspec.yaml
|
||||
flutter:
|
||||
shaders:
|
||||
- shaders/wave.frag
|
||||
```
|
||||
|
||||
## ❌ 안티패턴 (Anti-Patterns)
|
||||
```dart
|
||||
// 매 build-time precompiled, 매 runtime jank 의 X
|
||||
final program = await FragmentProgram.fromAsset('shaders/wave.frag');
|
||||
final shader = program.fragmentShader()
|
||||
..setFloat(0, size.width)
|
||||
..setFloat(1, size.height)
|
||||
..setFloat(2, time);
|
||||
canvas.drawRect(rect, Paint()..shader = shader);
|
||||
```
|
||||
|
||||
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
|
||||
### Performance overlay
|
||||
```dart
|
||||
MaterialApp(
|
||||
showPerformanceOverlay: true, // 매 GPU/UI thread frame time 의 visual
|
||||
home: MyApp(),
|
||||
);
|
||||
```
|
||||
|
||||
### Disable Impeller (debugging)
|
||||
```bash
|
||||
flutter run --no-enable-impeller
|
||||
```
|
||||
|
||||
### CustomPainter — Impeller 의 fast path
|
||||
```dart
|
||||
class WavePainter extends CustomPainter {
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final path = Path();
|
||||
for (double x = 0; x <= size.width; x += 2) {
|
||||
path.lineTo(x, sin(x * 0.05) * 20 + size.height / 2);
|
||||
}
|
||||
// 매 Impeller tessellator 가 GPU 친화 triangle 로 변환
|
||||
canvas.drawPath(path, Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 2);
|
||||
}
|
||||
@override bool shouldRepaint(_) => true;
|
||||
}
|
||||
```
|
||||
|
||||
### Backdrop blur (Impeller 의 optimized)
|
||||
```dart
|
||||
BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), // 매 Impeller GPU blur
|
||||
child: Container(color: Colors.black.withOpacity(0.3)),
|
||||
)
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Flutter 3.10+ iOS | Impeller default 유지 |
|
||||
| Flutter 3.27+ Android | Impeller (Vulkan) default 유지 |
|
||||
| 매 legacy device (Android API <29) | Skia fallback 자동 |
|
||||
| Custom shader 사용 | Impeller 의 IR precompile 활용 |
|
||||
| Engine bug 의심 | `--no-enable-impeller` 로 A/B |
|
||||
|
||||
**기본값**: 매 Impeller 활성화 유지 (Flutter 3.27+).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Flutter]] · [[Rendering-Engines]]
|
||||
- 변형: [[Skia]] · [[Metal]] · [[Vulkan]]
|
||||
- 응용: [[Flutter-Performance]] · [[Custom-Painter]]
|
||||
- Adjacent: [[Shader-Precompilation]] · [[Tessellation]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Flutter 앱 의 jank 진단, custom shader 작성, iOS/Android rendering 차이 디버깅.
|
||||
**언제 X**: web target (Flutter Web 은 CanvasKit/Skia), 매 Skia-specific API 의존 코드.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **runtime shader string compile**: Impeller 의 AOT 의 우회 — jank 재발.
|
||||
- **CustomPainter shouldRepaint=true 남발**: 매 frame 의 unnecessary repaint.
|
||||
- **legacy SKSL caching workaround 유지**: Impeller 환경에서 의미 없음, 코드 cleanup 필요.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Flutter docs `flutter.dev/perf/impeller`, Flutter 3.27 release notes).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Impeller engine architecture 정리 |
|
||||
|
||||
Reference in New Issue
Block a user