Flutter 기초
Flutter 기초
Flutter 는 Google 이 만든 UI 툴킷으로, 한 코드베이스에서 모바일 · 웹 · 데스크탑을 모두 겨냥. 자체 렌더링 엔진과 Dart 언어, 그리고 위젯 트리라는 표현 모델이 핵심. 이 글은 Flutter 의 출자 · Dart 언어 · 위젯 모델 · 렌더링 엔진 (Skia · Impeller) · 빌드 · 패키지 생태계.
1. Flutter 의 출자
| 사건 | 시기 |
|---|---|
| "Sky" 로 알려진 초기 데모 | 2015 |
| Flutter alpha (Sky 가 Flutter 로 이름 변경) | 2017 |
| Flutter 1.0 GA | 2018-12 |
| Flutter 2.0 (웹 안정 · null safety) | 2021-03 |
| Flutter 3.0 (macOS · Linux 안정) | 2022-05 |
| Impeller 렌더러 (iOS) 기본 | 3.10 (2023) ~ 3.13 |
처음부터 "한 엔진, 모든 플랫폼" 을 목표로 설계. 플랫폼의 위젯을 부르는 대신 자체 렌더러로 모든 픽셀을 그림.
2. Dart 언어
| 사건 | 시기 |
|---|---|
| Dart 발표 (Google) | 2011 |
| Dart 1.0 | 2013 |
| Dart 2.0 (강한 타입) | 2018 |
| sound null safety (선택) | 2.12 (2021) |
| Dart 3.0 (sound null safety 강제 · 패턴 매칭 등) | 2023-05 |
Dart 는 처음에 자바스크립트 대안의 의도로 시작됐지만, Flutter 의 채택 이후 클라이언트 UI 언어로 자리.
특징:
- C 계열 문법, Java / JavaScript / TypeScript 와 친숙.
- AOT (Ahead-Of-Time) 와 JIT (Just-In-Time) 양쪽 지원 — 개발 시 JIT (핫 리로드), 릴리스 시 AOT (성능).
- sound null safety — 변수의 nullable 여부가 타입 시스템에 표현.
- 패턴 매칭 · records · sealed class (3.0+).
String greet(String? name) {
return switch (name) {
null => 'hello, friend',
String s when s.isEmpty => 'hello, friend',
String s => 'hello, $s',
};
}
3. 위젯 트리
Flutter 의 표현은 위젯 트리. 화면 전체가 위젯으로 구성되고, 위젯의 빌드 결과가 다시 위젯:
class HelloApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Hello')),
body: Center(child: Text('world')),
),
);
}
}
| 종류 | 의미 |
|---|---|
| StatelessWidget | 입력이 같으면 출력이 같음. 내부 상태 없음. |
| StatefulWidget | 자체 상태를 가짐. State 객체가 위젯 라이프사이클을 따라 삶. |
class Counter extends StatefulWidget {
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int count = 0;
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => setState(() => count++),
child: Text('$count'),
);
}
}
setState 가 호출되면 해당 서브트리가 다시 빌드.
4. 위젯 - 엘리먼트 - RenderObject
Flutter 내부는 세 트리:
- Widget Tree — 가벼운 설정 객체. 자주 새로 만들어짐.
- Element Tree — 위젯의 인스턴스. 라이프사이클을 가지고 자식 트리와의 매핑을 유지.
- RenderObject Tree — 실제 레이아웃 · 페인팅을 수행.
이 분리 덕분에 위젯 객체를 매번 새로 만들어도 비용이 작음. diff 는 element 트리에서 일어남.
5. 렌더링 엔진
Skia — Flutter 는 처음에 Skia (Chrome · Android 가 사용하는 2D 그래픽 엔진) 위에서 출발. CPU 와 GPU 모두 사용 가능하지만, Flutter 는 GPU 경로를 주로.
Impeller — iOS 의 첫 프레임 셔터 (jank) 가 자주 보고됨. 원인 중 하나가 Skia 의 셰이더 컴파일이 화면에 처음 등장할 때 일어나는 점. Impeller 는 이를 해결하기 위해 설계된 새 렌더러로, 셰이더를 빌드 시점에 미리 컴파일:
- iOS — 3.10 (2023) 에서 기본.
- Android — 점진적 활성화 (3.16 ~ 3.27 에서 단계적 기본 활성화).
- macOS · Web · Desktop — 작업 진행 중.
6. 개발 흐름
| 동작 | 의미 |
|---|---|
| Hot Reload | 변경된 코드만 주입. 위젯 트리는 유지, 상태도 보존. |
| Hot Restart | 앱 재시작. 상태 초기화. |
Hot Reload 는 Dart 의 JIT 가 가능하게 함. UI 디테일을 빠르게 반복 수정하는 자리에서 강점.
빌드 도구:
flutter create app— 프로젝트 생성.flutter run— 디바이스 / 에뮬레이터에서 실행.flutter build apk|ipa|web|windows|macos|linux— 플랫폼별 산출물.flutter pub get— 패키지 가져오기.flutter pub upgrade— 갱신.dart format·flutter analyze— 포맷 · 린트.
Mac · Linux 와 Windows 명령은 동일.
7. pub.dev 와 패키지
Dart · Flutter 의 공식 패키지 저장소. 점수 시스템 (파이크) 으로 메인테넌스 · 플랫폼 호환 · 문서를 평가.
| 카테고리 | 패키지 |
|---|---|
| 상태 관리 | provider · riverpod · bloc · get_it |
| 라우팅 | go_router · auto_route |
| HTTP | dio · http |
| 로컬 DB | sqflite · drift · isar · hive |
| 직렬화 | json_serializable · freezed |
| 로컬 저장 | shared_preferences · flutter_secure_storage |
| 푸시 | firebase_messaging |
8. 상태 관리
Flutter 자체는 setState 와 InheritedWidget 만 제공. 더 큰 앱에서는 외부 상태 관리 패키지:
- Provider — 공식 권장에서 시작. 단순.
- Riverpod — Provider 의 후속. 컴파일 타임 안전성.
- Bloc / Cubit — 이벤트 → 상태 흐름. 테스트 가능성.
- GetX — 의존성 · 라우팅 · 상태를 묶음. 단순함이 강점 · 구조 강제는 약점.
- MobX — 반응형 모델.
선택은 팀의 친숙도 · 앱 크기에 영향.
9. 플랫폼 채널 · 적응형 UI
플랫폼 채널 — 네이티브 코드 호출이 필요할 때 MethodChannel · EventChannel · BasicMessageChannel. iOS 는 Swift / Obj-C, Android 는 Kotlin / Java 로 작성.
적응형 UI — iOS 의 Cupertino · Android 의 Material 위젯이 별도 라이브러리로 제공. Platform.isIOS 로 분기하거나 flutter_platform_widgets 같은 추상화 패키지.
10. 자주 걸리는 자리
번들 크기 — Hello World 가 수 MB 단위. 자체 엔진을 포함하기 때문. 텍스트 압축 · 코드 분할이 일반 웹만큼 자유롭지 않음.
iOS 첫 프레임 jank — Impeller 도입 이전의 흔한 보고. 이후 개선됐지만 자체 셰이더가 많은 자리에서는 여전히 점검 필요.
플랫폼 위젯의 부재 — 새 iOS · Android UI 컨트롤이 즉시 들어오지 않음. Flutter 가 따라가야.
접근성 트리 — 자체 그리기 모델이라 OS 의 접근성과 별도 매핑이 필요. 라벨 누락 시 스크린 리더 부적절.
웹 타깃의 한계 — Flutter Web 은 Skia (canvaskit) 또는 HTML 백엔드. 검색 엔진 인덱싱 · 접근성 · 번들 크기에서 일반 웹 프레임워크 대비 약점.
상태 관리 분파 — 선택지가 너무 많아 결정 비용이 큼. 팀 규약 필요.
Dart 패키지 다양성 — Node · Python 만큼은 아님. 일부 자리에서 직접 구현 필요.
OS 업데이트 호환 — 매년 SDK 변경 시 일부 패키지가 깨짐. 라이브러리 메인테넌스 활동성 점검.
하고픈 말
Flutter 는 자체 캔버스 모델로 픽셀 단위 일관성을 가져온 도구. Dart 의 sound null safety + 패턴 매칭 + AOT / JIT 양쪽 지원이 토대. 한계는 번들 크기 + 플랫폼 위젯 추적 + 접근성 매핑 + 웹 타깃의 약점. 60 / 120 fps 애니메이션이 절실한 자리, 일관된 픽셀이 사업 가치인 자리에 가장 잘 어울립니다.
Next
- android-build-apk
- ios-build
Flutter 공식 문서 · Dart 공식 문서 · Flutter Codelabs · pub.dev · Impeller 소개 · Flutter Engine GitHub · Effective Dart · Flutter Samples 를 참고합니다.