Flutter 앱 빌드 시간 40% 단축한 방법

문제 상황

프로젝트가 2년차에 접어들면서 Flutter 앱의 빌드 시간이 로컬에서 8분, CI에서 12분까지 늘어났다. 위젯 수가 500개를 넘고, 의존성 패키지도 80개 이상이 되면서 발생한 문제였다.

적용한 최적화

1. 빌드 캐시 활용

# .github/workflows/build.yml
- uses: actions/cache@v3
  with:
    path: |
      ~/.pub-cache
      build/
    key: ${{ runner.os }}-flutter-${{ hashFiles('**/pubspec.lock') }}

GitHub Actions에서 pub 캐시와 빌드 아티팩트를 캐싱했다. 이것만으로 CI 빌드가 7분으로 줄었다.

2. 불필요한 rebuild 제거

class ProductCard extends StatelessWidget {
  final Product product;
  
  const ProductCard({Key? key, required this.product}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return const로 선언 가능한 위젯은 모두 const로 변경
  }
}

Flutter DevTools의 Performance 탭으로 불필요한 rebuild를 찾아냈다. const 생성자를 일관되게 적용하고, flutter analyzeprefer_const_constructors 규칙을 추가했다.

3. 코드 생성 병렬화

Freezed, json_serializable 등 코드 생성 패키지를 많이 사용했는데, 빌드 단계에서 순차 실행되고 있었다.

# 기존
flutter pub run build_runner build --delete-conflicting-outputs

# 개선
flutter pub run build_runner build --delete-conflicting-outputs --concurrency=4

4. 네이티브 빌드 최적화

iOS 빌드에서 시간이 많이 소요됐다. Xcode 빌드 설정을 조정했다.

# ios/Podfile
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_COMPILATION_MODE'] = 'wholemodule'
      config.build_settings['COMPILER_INDEX_STORE_ENABLE'] = 'NO'
    end
  end
end

결과

  • 로컬 빌드: 8분 → 5분
  • CI 빌드: 12분 → 7분
  • Hot reload: 2초 → 0.8초

빌드 시간이 체감상 확실히 개선됐다. 특히 캐싱 적용이 가장 효과가 컸고, 나머지는 점진적 개선이었다. 다음은 Dart 3의 record와 pattern matching을 도입해서 코드 생성 의존도를 낮춰볼 계획이다.