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에서는 충분히 활용 가능하다는 결론이다.

Flutter 웹 앱 빌드 최적화 - 초기 로딩 시간 줄이기