Flutter 包体积优化实战:减少 APK/IPA 大小
Flutter 应用在发布时,包体积是用户最直观的感受之一。过大的包会增加用户下载的门槛,影响转化率。本文系统梳理 Flutter 包体积优化的可落地方案。
一、分析包体积的工具
1.1 使用 --analyze-size 分析
# Android 分析
flutter build apk --release --analyze-size
# iOS 分析(需要先 build)
flutter build ios --release --analyze-size
# 分析结果会生成一个 .json 文件,用 DevTools 查看
flutter pub global run devtools --appSizeBase=build/flutter-size-analysis_xxx.json
1.2 使用 flutter build apk --split-per-abi
# 按 ABI 拆分 APK,减少每个 APK 的体积
flutter build apk --release --split-per-abi
# 生成的文件:
# app-armeabi-v7a-release.apk (约 减少 30%)
# app-arm64-v8a-release.apk (约 减少 30%)
# app-x86_64-release.apk (模拟器用)
二、移除未使用的资源
2.1 移除未使用的图标
检查 pubspec.yaml 中声明的资源是否都有使用:
# ❌ 避免:声明整个目录(会打包所有文件)
flutter:
assets:
- assets/images/
# ✅ 推荐:只声明需要的文件
flutter:
assets:
- assets/images/logo.png
- assets/images/placeholder.png
2.2 使用 --track-widget-creation 移除未使用的 Widget
# 发布构建时默认启用,确保没有关闭
flutter build apk --release
# 不需要额外参数,默认会 tree-shake 未使用的 Widget
三、图片优化
3.1 使用 WebP 格式
WebP 格式比 PNG/JPG 小 25-35%:
# 批量转换 PNG 到 WebP(需要安装 WebP 工具)
# 下载:https://developers.google.com/speed/webp/docs/precompiled
# 转换单张图片(有损,质量 80)
cwebp -q 80 input.png -o output.webp
# 批量转换(Linux/macOS)
for file in assets/images/*.png; do
cwebp -q 80 "$file" -o "${file%.png}.webp"
done
# 批量转换(Windows PowerShell)
Get-ChildItem "assets\images\*.png" | ForEach-Object {
cwebp -q 80 $_.FullName -o ($_.FullName -replace '\.png$', '.webp')
}
3.2 使用 flutter_image_compress 压缩网络图片
# pubspec.yaml
dependencies:
flutter_image_compress: ^2.1.0
import 'package:flutter_image_compress/flutter_image_compress.dart';
Future<Uint8List?> compressImage(File file) async {
final result = await FlutterImageCompress.compressWithFile(
file.absolute.path,
minWidth: 1024,
minHeight: 1024,
quality: 80,
format: CompressFormat.jpeg,
);
return result;
}
四、代码优化
4.1 使用 @pragma('vm:entry-point') 避免混淆问题
// 如果使用了混淆,确保反射调用的类不被 tree-shake
@pragma('vm:entry-point')
class MyReflectionClass {
final String name;
MyReflectionClass(this.name);
}
4.2 启用代码混淆(Android)
// app/build.gradle
android {
buildTypes {
release {
minifyEnabled true // 启用代码混淆
shrinkResources true // 移除未使用的资源
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
proguard-rules.pro:
# 保留 Flutter 相关类
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
# 保留 JSON 序列化类(如果使用了 json_serializable)
-keep class com.example.app.models.** { *; }
-keepattributes *Annotation*
五、字体优化
5.1 只打包需要的字体字形
如果使用了中文字体,字体文件可能非常大(3-10MB)。
方案1:使用 flutter_font_otf 裁剪字体
# 安装 fonttools
pip install fonttools brotli
# 裁剪字体(只保留用到的字形)
pyftsubset font.otf --text="你需要的字符" --output-file=font.subset.otf
方案2:使用 flutter_launcher_icons 时将图标字体替换为图片
# 如果使用了 iconfont,考虑替换为 svg/png
# flutter_svg 支持 SVG,体积比 iconfont 小
六、Gradle 配置优化(Android)
6.1 启用 Resource 缩减
// app/build.gradle
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true // 缩减资源
// 指定需要保留的资源
resValue "string", "app_name", "My App"
}
}
// 启用构建缓存
buildCache {
local {
enabled = true
}
}
}
6.2 使用 AAB(Android App Bundle)
# AAB 格式可以让 Google Play 按需下发资源,减少用户下载大小
flutter build appbundle --release
# 上传到 Google Play 时,Google Play 会为每台设备生成最优的 APK
# 平均减少 20-30% 的下载大小
七、iOS 包体积优化
7.1 启用 Bitcode(已废弃,但可以做其他优化)
# iOS 构建时启用 Release 模式优化
flutter build ios --release
# 在 Xcode 中:
# 1. 设置 Build Settings → Swift Compiler - Optimization Level → Release → Optimize for Speed [-O]
# 2. 设置 Build Settings → Dead Code Stripping → Yes
# 3. 设置 Build Settings → Strip Debug Symbols During Copy → Yes
7.2 移除未使用的架构
# ios/Podfile 中添加
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
# 只保留 arm64 架构(iOS 14+ 不需要 armv7)
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'i386'
end
end
end
八、优化效果对比表
| 优化手段 | 预计减少体积 | 实施难度 | 优先级 |
|---|---|---|---|
--split-per-abi | 30% | 低 | P0 |
| 图片转 WebP | 25-35% | 低 | P0 |
| 启用混淆 + 资源缩减 | 10-20% | 中 | P1 |
| 使用 AAB 格式 | 20-30% | 低 | P1 |
| 字体子集化 | 50-80%(字体文件) | 高 | P2 |
| 移除未使用资源 | 5-15% | 中 | P1 |
九、检查清单
完成包体积优化后,建议对照以下清单进行检查:
- 已使用
--split-per-abi或 AAB 格式发布 - 所有图片已转换为 WebP 格式
- 已启用代码混淆和资源缩减
- 未使用的资源已从
pubspec.yaml中移除 - 中文字体已做子集化处理(如果使用了中文字体)
- 使用
--analyze-size分析了包体积构成 - Release 包体积 < 20MB(Android)、< 30MB(iOS)
十、参考资源
如果本文对你有帮助,欢迎点赞收藏。如果你有更好的包体积优化方案,欢迎在评论区分享。