Flutter 웹 앱 빌드 최적화 - 초기 로딩 시간 줄이기
문제 상황
사내 어드민 도구를 Flutter 웹으로 개발했다. 모바일 앱과 코드를 공유할 수 있다는 장점 때문에 선택했는데, 프로덕션 빌드 후 확인해보니 초기 로딩이 심각하게 느렸다.
- main.dart.js: 3.2MB
- 첫 화면 렌더링: 5.3초
- Lighthouse 점수: 27점
적용한 최적화
1. Deferred Loading
Flutter는 deferred as 키워드로 코드 스플리팅을 지원한다. 당장 필요하지 않은 페이지는 나중에 로드하도록 변경했다.
import 'package:flutter/material.dart';
import 'screens/dashboard.dart';
import 'screens/settings.dart' deferred as settings;
import 'screens/reports.dart' deferred as reports;
class AppRouter {
static Route<dynamic> generateRoute(RouteSettings routeSettings) {
switch (routeSettings.name) {
case '/settings':
return MaterialPageRoute(
builder: (_) => FutureBuilder(
future: settings.loadLibrary(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return settings.SettingsPage();
}
return LoadingPage();
},
),
);
// ...
}
}
}
2. CanvasKit vs HTML Renderer
Flutter 웹은 두 가지 렌더러를 제공한다. 기본값인 CanvasKit은 고품질이지만 무겁다. 사내 어드민은 UI가 복잡하지 않아서 HTML 렌더러로 변경했다.
flutter build web --web-renderer html --release
CanvasKit: 3.2MB → HTML: 1.8MB로 줄었다.
3. Font Subset
Google Fonts를 사용 중이었는데, 한글 폰트가 용량의 상당 부분을 차지했다. 필요한 글자만 포함하도록 subset을 만들었다.
flutter:
fonts:
- family: NotoSansKR
fonts:
- asset: fonts/NotoSansKR-subset.woff2
결과
- main.dart.js: 1.8MB (44% 감소)
- 첫 화면 렌더링: 2.1초 (60% 개선)
- Lighthouse 점수: 58점
여전히 React SPA보다는 무겁지만, 사내 도구로는 충분히 쓸 만해졌다. Flutter 웹은 아직 프로덕션 레디는 아니지만, 특정 use case에서는 충분히 활용 가능하다는 결론이다.