- Sử dụng Flutter DevTools toàn diện: Inspector, Performance, Memory, Network, Logging.
- Hiểu Performance Overlay (GPU + UI thread).
- Tối ưu rebuild:
const,RepaintBoundary, selector pattern. - Build release: APK, App Bundle, IPA, macOS app, web.
- Sign Android (keystore) + iOS (cert + provisioning).
- Deploy: Google Play, App Store, Firebase App Distribution, TestFlight.
- Web deploy: Firebase Hosting, Cloudflare Pages.
- Flavor: dev/staging/prod build.
- Crash reporting + Analytics.
- App size optimization.
1. Performance Overlay
MaterialApp(
showPerformanceOverlay: true, // 2 bar overlay góc phải
)
Output 2 bar:
- UI thread (Dart) — build/layout time. Code Dart bạn viết chạy ở đây.
- Raster thread (GPU) — paint time. Skia/Impeller render lên screen.
Mỗi vạch = 1 frame (16.67ms ở 60Hz, 8.33ms ở 120Hz). Đỏ = vượt budget → jank.
Debug mode chậm hơn release 10-100x do JIT + debug overhead. Đo perf phải dùng Profile mode:
flutter run --profile
2. Flutter DevTools — 6 panel chính
2.1 Widget Inspector
- Xem widget tree đầy đủ, click widget trên app → highlight trong tree.
- Property inspect: size, position, style.
- Toggle "Select Widget Mode" — tap app để select.
- Show layout guideline (border + padding) — debug layout phức tạp.
2.2 Performance
- Record CPU trace.
- Flame chart hiển thị thời gian mỗi function call.
- Identify slow widget build.
- Frame chart: mỗi frame một bar màu — đỏ = jank.
2.3 CPU Profiler
- Sampling profiler — đếm function chiếm CPU nhiều nhất.
- Bottom-up / top-down view.
2.4 Memory
- Heap snapshot.
- Allocation timeline.
- Detect leak: object không được GC sau khi widget unmount.
2.5 Network
- Log HTTP request, response, timing.
- Filter URL, status code.
- Inspect headers + body.
2.6 Logging
import 'dart:developer';
log('fetched user', name: 'api', level: 800);
log('error', name: 'api', level: 1000, error: e, stackTrace: st);
// debugPrint tránh truncate Android log
debugPrint('long output...');
3. 6 lỗi perf phổ biến + fix
| Issue | Fix |
|---|---|
| Rebuild quá nhiều (widget không thay đổi vẫn rebuild) | const constructor + tách widget thành class riêng, BlocSelector / Provider.select |
Opacity widget expensive (offscreen layer) | Dùng AnimatedOpacity hoặc Color.withOpacity background |
ClipPath repaint mỗi frame | Wrap với RepaintBoundary |
| Long list không lazy | ListView.builder thay ListView(children: [...]) |
| Image lớn không resize | Image.network(..., cacheWidth: 200, cacheHeight: 200) hoặc ResizeImage |
| State update granular thiếu | Selector / BlocSelector rebuild chỉ subset |
const constructor — perf hint chính
// ❌
Text('Hello')
// ✅ — không rebuild khi parent rebuild
const Text('Hello')
// Bật lint
// analysis_options.yaml
linter:
rules:
- prefer_const_constructors
- prefer_const_literals_to_create_immutables
- prefer_const_declarations
ListView.builder lazy
// ❌ — build 1000 widget ngay từ đầu
ListView(children: items.map((i) => ItemTile(i)).toList())
// ✅ — chỉ build widget visible
ListView.builder(
itemCount: items.length,
itemBuilder: (ctx, i) => ItemTile(items[i]),
)
Image cacheWidth
// ❌ — load full size 4000x4000
Image.network(url)
// ✅ — resize ở memory, hiển thị 200x200
Image.network(url, cacheWidth: 200, cacheHeight: 200)
4. Build mode — Debug / Profile / Release
| Debug | Profile | Release | |
|---|---|---|---|
| Compile | JIT | AOT | AOT |
| Hot reload | Có | Không | Không |
| Assertion | Bật | Bật | Tắt |
| DevTools | Full | Performance only | Không |
| Perf | Chậm | Gần production | Production |
| Lệnh | flutter run | flutter run --profile | flutter build apk --release |
5. Build Android APK
flutter build apk --release
# Output: build/app/outputs/flutter-apk/app-release.apk
# Split per ABI (giảm 50% size — mỗi ABI 1 APK)
flutter build apk --release --split-per-abi
# Output:
# app-arm64-v8a-release.apk
# app-armeabi-v7a-release.apk
# app-x86_64-release.apk
6. Android App Bundle (AAB)
flutter build appbundle --release
# Output: build/app/outputs/bundle/release/app-release.aab
Google Play khuyến nghị AAB. Google Play split per-device download — user tải nhỏ hơn.
7. Android signing
Generate keystore
keytool -genkey -v -keystore ~/upload-keystore.jks \
-keyalg RSA -keysize 2048 -validity 10000 -alias upload
# Nhập password + thông tin (CN, OU, O, City, State, Country)
# OUTPUT: upload-keystore.jks
android/key.properties
storePassword=your_store_password
keyPassword=your_key_password
keyAlias=upload
storeFile=/Users/yourname/upload-keystore.jks
KHÔNG commit file này — add vào .gitignore.
Update android/app/build.gradle
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Mất keystore = không update app trên Play được. Backup multiple location (Google Drive, USB, password manager). Mất keystore phải release app mới với package name khác → mất user, review.
8. Build iOS IPA
flutter build ipa --release
# Output: build/ios/ipa/Runner.ipa
9. iOS signing
iOS signing là pain point. Cần:
- Apple Developer account ($99/năm).
- App ID — register Bundle ID trên Apple Developer Portal.
- Certificate — Development + Distribution (.p12).
- Provisioning Profile — link App ID + Certificate.
- Team — Xcode Signing & Capabilities.
Automatic vs Manual signing
- Automatic: Xcode tự handle. Pros: dễ. Cons: đôi khi vẽ cert sai, đặc biệt với CI.
- Manual: control đầy đủ. Pros: reliable cho CI. Cons: setup phức tạp.
Production team thường dùng fastlane match để sync cert + profile qua git encrypted.
10. macOS app
flutter build macos --release
# Output: build/macos/Build/Products/Release/MyApp.app
# Notarize cho distribute outside App Store
xcrun notarytool submit MyApp.app.zip --keychain-profile "AC_PASSWORD" --wait
xcrun stapler staple MyApp.app
11. Build Web
flutter build web --release
# Output: build/web/
CanvasKit vs HTML renderer
| CanvasKit | HTML | |
|---|---|---|
| Render | WebAssembly + Skia | HTML/CSS + Canvas |
| Size | ~2MB lib | Nhẹ hơn |
| Consistency | Pixel-perfect with mobile | Browser-native, có thể khác |
| SEO | Kém (canvas) | Tốt hơn |
| Use case | App giống mobile, animation phức tạp | App content-heavy, SEO matter |
# Force HTML renderer
flutter build web --web-renderer html --release
# Force CanvasKit
flutter build web --web-renderer canvaskit --release
# Auto (default): CanvasKit trên desktop, HTML trên mobile
12. Web hosting
Firebase Hosting
npm install -g firebase-tools
firebase login
firebase init hosting
# Choose: build/web as public, configure as SPA → yes
flutter build web --release
firebase deploy --only hosting
# URL: https://your-project.web.app
Alternatives
- Cloudflare Pages — free, custom domain, CDN edge.
- Netlify / Vercel — same idea, drag-drop hoặc git integration.
- GitHub Pages — free, push
build/weblên gh-pages branch.
13. Firebase App Distribution
Internal testing — upload AAB/IPA, invite tester qua email.
npm install -g firebase-tools
firebase login
# Upload Android AAB
firebase appdistribution:distribute build/app/outputs/bundle/release/app-release.aab \
--app YOUR_FIREBASE_APP_ID \
--groups testers
# Upload iOS IPA
firebase appdistribution:distribute build/ios/ipa/Runner.ipa \
--app YOUR_FIREBASE_APP_ID \
--groups testers
14. TestFlight (iOS beta)
- Build IPA:
flutter build ipa --release. - Upload qua Xcode Organizer hoặc Transporter app.
- App Store Connect → TestFlight → External Testing → add tester.
- Tester nhận email + cài qua TestFlight app.
- External tester cần Apple review (~1 ngày), internal không.
15. Google Play Console
4 testing track:
- Internal testing — instant, max 100 tester.
- Closed testing — invite, Google review ~1h.
- Open testing — public beta link.
- Production — live trên Play Store.
flutter build appbundle --release
# Upload manually qua Play Console UI
# Hoặc tự động: fastlane supply
16. Flavor — multi env
Build dev/staging/prod với config khác (bundle id, app name, API endpoint, Firebase project).
Android — productFlavors
// android/app/build.gradle
android {
flavorDimensions "env"
productFlavors {
dev {
dimension "env"
applicationIdSuffix ".dev"
resValue "string", "app_name", "MyApp Dev"
}
staging {
dimension "env"
applicationIdSuffix ".staging"
resValue "string", "app_name", "MyApp Staging"
}
prod {
dimension "env"
resValue "string", "app_name", "MyApp"
}
}
}
iOS — Xcode schemes
iOS không có productFlavor như Android — cần tạo Xcode schemes thủ công. Steps: Product → Scheme → New Scheme → Duplicate "Runner" cho mỗi env.
Dart — entry point per flavor
// lib/main_dev.dart
import 'app.dart';
void main() => runApp(App(env: 'dev', apiUrl: 'https://api-dev.example.com'));
// lib/main_staging.dart
void main() => runApp(App(env: 'staging', apiUrl: 'https://api-staging.example.com'));
// lib/main_prod.dart
void main() => runApp(App(env: 'prod', apiUrl: 'https://api.example.com'));
# Run
flutter run --flavor dev -t lib/main_dev.dart
flutter run --flavor staging -t lib/main_staging.dart
# Build
flutter build apk --flavor prod --release -t lib/main_prod.dart
17. CI/CD intro
Options
- fastlane — Ruby tool, mạnh nhất cho mobile. Match (signing), Pilot (TestFlight), Supply (Play).
- Codemagic — Flutter-first CI, dễ setup.
- Bitrise — mobile-focused CI.
- GitHub Actions — free for open source, free tier limit.
GitHub Actions example
# .github/workflows/deploy.yml
name: Deploy
on:
push:
tags: ['v*']
jobs:
android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with: { flutter-version: '3.22.0', channel: stable }
- run: flutter pub get
- run: flutter test
- run: flutter build appbundle --release --flavor prod -t lib/main_prod.dart
env:
# decode keystore từ secret
KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
- uses: actions/upload-artifact@v4
with:
name: aab
path: build/app/outputs/bundle/prodRelease/app-prod-release.aab
ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
- run: flutter build ipa --release
# Upload via fastlane pilot...
18. Crash reporting
Capture exception runtime production. 2 options chính:
- Firebase Crashlytics — free, tích hợp Firebase.
- Sentry — feature richer, có self-host option.
flutter pub add firebase_core firebase_crashlytics
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Catch Flutter framework error
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
// Catch async / platform error
PlatformDispatcher.instance.onError = (e, st) {
FirebaseCrashlytics.instance.recordError(e, st, fatal: true);
return true;
};
runApp(const MyApp());
}
// Manual log
FirebaseCrashlytics.instance.log('user clicked checkout');
FirebaseCrashlytics.instance.setUserIdentifier(user.id);
19. Analytics
- Firebase Analytics — free, integration với Firebase suite.
- Mixpanel — event-based, free tier.
- Amplitude — product analytics.
- PostHog — open source, self-host được.
await FirebaseAnalytics.instance.logEvent(
name: 'purchase',
parameters: {'item_id': 'sku123', 'value': 99.99},
);
20. App size optimization
# Phân tích size
flutter build apk --analyze-size
flutter build appbundle --analyze-size
# Output: bảng size component, font, asset, code
Tips giảm size
--split-per-abiAndroid — 50% nhỏ hơn.--tree-shake-icons— chỉ include Material icon dùng.- Compress image: WebP thay PNG, JPEG quality 70-80%.
- Remove unused asset trong
pubspec.yaml. - Font subset — chỉ ship glyph dùng (vd Vietnamese subset).
- Audit dependencies — bỏ package nặng không dùng.
21. Launcher icons + splash
flutter_launcher_icons
flutter pub add --dev flutter_launcher_icons
# pubspec.yaml
flutter_launcher_icons:
android: true
ios: true
image_path: "assets/icon/icon.png" # 1024x1024 PNG
adaptive_icon_background: "#FFFFFF"
adaptive_icon_foreground: "assets/icon/foreground.png"
web:
generate: true
macos:
generate: true
dart run flutter_launcher_icons
# Sinh icon cho tất cả platform
flutter_native_splash
flutter_native_splash:
color: "#FFFFFF"
image: assets/splash.png
android_12:
image: assets/splash_android12.png
color: "#FFFFFF"
dart run flutter_native_splash:create
22. Bài tập
Perf optimize ListView 1000 item
Bật Performance Overlay. Scroll ListView 1000 item — UI bar đỏ.
Optimize bằng ListView.builder + const + RepaintBoundary.
Đo lại, đỏ → xanh.
💡 Gợi ý đáp án
3 step: (1) ListView → ListView.builder, (2) const cho item widget, (3) RepaintBoundary wrap item heavy paint.
Build signed APK
Build release APK signed với keystore tự sinh. Cài lên Android device thực tế.
💡 Gợi ý đáp án
Tham khảo section 5-7. keytool → key.properties → build.gradle signingConfigs → flutter build apk --release → adb install.
TestFlight upload
Build IPA, upload TestFlight, gửi cho 1 tester thật.
💡 Gợi ý đáp án
Cần Apple Developer account ($99/năm). flutter build ipa → upload via Xcode Organizer → TestFlight UI invite tester email.
Setup 3 flavor
Setup 3 flavor (dev/staging/prod) với 3 API endpoint khác. Run + build từng flavor.
💡 Gợi ý đáp án
Tham khảo section 16. Android productFlavors + iOS schemes + 3 entry point Dart.
GitHub Actions CI
CI GitHub Actions: trigger merge to main → build APK + web → upload Firebase App Distribution.
💡 Gợi ý đáp án
Workflow file (section 17). Secret keystore (base64 encode). firebase-cli action cho App Distribution.
23. Quiz
APK vs AAB — Google Play khuyến nghị?
Xem đáp án
Đáp án: AAB (App Bundle). Google split per-device, download nhỏ hơn 50%+.
Profile mode khác Release?
Xem đáp án
Đáp án: Profile = AOT + profile flag (cho DevTools track). Slight slower than Release. Dùng để đo perf gần production. Không hot reload.
Web CanvasKit vs HTML — chọn nào?
Xem đáp án
Đáp án: CanvasKit feature đầy đủ, giống mobile (~2MB). HTML nhẹ, SEO tốt, một số widget không support hoàn hảo. Default: Flutter pick auto.
iOS auto signing — vấn đề?
Xem đáp án
Đáp án: Cần đăng nhập Apple Developer, đôi khi vẽ cert sai. Manual signing đáng tin cho CI. fastlane match là solution mature.
App size lớn — trick giảm?
Xem đáp án
Đáp án: --split-per-abi, --tree-shake-icons, remove unused asset, dùng WebP, font subset, audit deps.
Flavor Android setup file nào?
Xem đáp án
Đáp án: android/app/build.gradle trong android { flavorDimensions ... productFlavors { dev {}, staging {}, prod {} } }.
Firebase Crashlytics capture exception nào?
Xem đáp án
Đáp án: Native crash + Dart uncaught. Cần setup FlutterError.onError + PlatformDispatcher.instance.onError.
Hot reload hoạt động mode nào?
Xem đáp án
Đáp án: Chỉ Debug (JIT). Profile/Release là AOT — code đã native binary.
24. Tổng kết
- ✅ Performance Overlay 2 bar (UI + Raster), 16ms threshold.
- ✅ DevTools 6 panel: Inspector, Performance, CPU, Memory, Network, Logging.
- ✅ 6 lỗi perf phổ biến + fix.
- ✅ Build mode: Debug (JIT, dev) / Profile (AOT, đo) / Release (AOT, ship).
- ✅ Android: APK + AAB. AAB chuẩn cho Play.
- ✅ Signing Android: keystore + key.properties + build.gradle signingConfigs.
- ✅ iOS: IPA + Xcode signing (cert + provisioning).
- ✅ Web: CanvasKit vs HTML renderer.
- ✅ Deploy: Firebase Hosting / TestFlight / Play Console.
- ✅ Flavor multi-env: Android productFlavors + iOS schemes.
- ✅ CI/CD: fastlane, GitHub Actions, Codemagic.
- ✅ Crash report: Crashlytics. Analytics: Firebase.
- ✅ App size: split-per-abi, tree-shake-icons, WebP.
- ✅ Launcher icons + splash via package.
25. Tổng kết Flutter curriculum
Bạn vừa hoàn thành 15 chương Flutter. Chương trình bao gồm:
- Setup, FVM, toolchain.
- Widget Tree mental model.
- Layout system, constraints.
- Material 3, theming, dark mode.
- Navigation, go_router, deep link.
- State foundation: setState + InheritedWidget.
- flutter_bloc deep dive.
- Provider / Riverpod / GetX comparison.
- Forms & input.
- Network: HTTP, Dio, Retrofit, repository pattern.
- Local storage: SharedPreferences → Drift, Hive, Isar.
- Animation: implicit / explicit / Hero / Lottie.
- Custom Paint & 3 cây render.
- Testing 4 level + CI.
- Performance + Deploy production.
Bạn đã có nền tảng để build production Flutter app. Bước tiếp theo:
- Build side project end-to-end — apply 15 chương vào 1 app thật.
- Đọc code mở các Flutter app lớn (Wonderous, Reflectly, FlutterFire samples).
- Theo dõi Flutter team channel: YouTube, blog medium, Flutter Forward conference.
- Đóng góp package mở trên pub.dev khi feel comfortable.
Hoàn thành Pillar 9 Programming Language — kết thúc 9 trụ cột IT Basic. Chúc bạn ship được app đầu tiên!