Why does the first Flutter app build take so long?

#flutter#build#gradle#xcode#compilation#performance

Answer

Overview

The first

text
flutter run
or
text
flutter build
is significantly slower than subsequent builds. This is because Flutter must perform many one-time setup tasks that are cached for later builds.


Reasons for Slow First Build

1. Gradle Dependency Download (Android)

Gradle downloads all Android dependencies, SDKs, and plugins for the first time. This includes the Android SDK build tools, Kotlin compiler, AndroidX libraries, and all transitive dependencies.

text
# What Gradle downloads on first build:
- Android SDK platform (e.g., API 34)
- Kotlin stdlib & compiler
- AndroidX libraries (appcompat, material, etc.)
- Flutter embedding (flutter.jar)
- All plugin dependencies (firebase, camera, etc.)
- Gradle wrapper itself

2. CocoaPods Setup (iOS)

For iOS, CocoaPods downloads and compiles all native pods. The first

text
pod install
fetches the CocoaPods spec repo and installs all native dependencies.

text
# What CocoaPods does on first build:
- Downloads CocoaPods master spec repo (~2GB)
- Resolves pod dependencies (Podfile.lock)
- Downloads native iOS libraries
- Compiles each pod into frameworks

3. Dart Compilation

The Dart compiler must process all source code — your app code, all packages from

text
pub get
, and the Flutter framework itself.

text
# Compilation modes:
- Debug:   JIT (Just-In-Time) + kernel snapshot
- Profile: AOT (Ahead-Of-Time) compilation
- Release: Full AOT + tree shaking + minification

4. Flutter Engine Initialization

The Flutter engine binary (written in C++) must be downloaded and linked for the target platform and architecture (ARM64, x86_64, etc.).

5. Code Generation

If your project uses

text
build_runner
(for
text
json_serializable
,
text
freezed
,
text
retrofit
, etc.), the first build generates all
text
.g.dart
and
text
.freezed.dart
files.

6. Asset Processing

Flutter processes and bundles all assets listed in

text
pubspec.yaml
— images, fonts, JSON files — and creates an asset manifest.


Why Subsequent Builds Are Faster

TaskFirst BuildSubsequent Builds
Gradle dependenciesDownloads everythingCached in
text
~/.gradle/
CocoaPodsFull pod installUses
text
Podfile.lock
cache
Dart compilationFull compileIncremental (only changed files)
Flutter engineDownloads engineAlready cached
Code generationFull generationOnly regenerates changed parts
Hot ReloadNot availableSub-second updates

Typical First Build Times

PlatformFirst BuildSubsequent BuildsHot Reload
Android (Debug)2-5 minutes10-30 seconds< 1 second
iOS (Debug)3-8 minutes15-45 seconds< 1 second
Android (Release)3-7 minutes1-3 minutesN/A
iOS (Release)5-15 minutes2-5 minutesN/A

How to Speed Up First Build

bash
# 1. Pre-download dependencies before running
flutter pub get

# 2. Use a faster Gradle mirror (in android/build.gradle)
# Replace google() and mavenCentral() with mirror URLs if behind slow network

# 3. Increase Gradle memory (in android/gradle.properties)
org.gradle.jvmargs=-Xmx4096m
org.gradle.parallel=true
org.gradle.caching=true

# 4. For iOS — use pre-built pods cache
cd ios && pod install --repo-update

# 5. Avoid unnecessary plugins
# Each plugin adds native compilation time

How to Speed Up Subsequent Builds

bash
# Use Hot Reload (preserves state) — press 'r' in terminal
# Use Hot Restart (resets state) — press 'R' in terminal

# Enable Impeller (faster rendering engine, default on iOS)
flutter run --enable-impeller

# Skip unnecessary targets
flutter build apk --target-platform android-arm64  # Only ARM64

What Slows Down Builds the Most

FactorImpactSolution
Many pluginsHigh — each adds native compilationRemove unused plugins
Large assetsMedium — processing timeCompress images, use WebP
Code generationMedium — build_runner overheadUse
text
build_runner watch
Slow networkHigh on first buildUse local mirrors or VPN
Low RAMHigh — Gradle is memory-hungryAllocate more JVM memory

Key Insight: The first build is slow because it performs many one-time tasks (downloading, compiling, caching). Subsequent builds reuse these caches and only recompile changed code. Hot Reload bypasses compilation entirely, injecting changed Dart code in under a second.