Flutter difference between (debug , release , profile )build
#flutter
Answer
Overview
Flutter supports three build modes: Debug, Release, and Profile. Each mode is optimized for different stages of development and has different performance characteristics.
Debug Mode
Purpose: Development and debugging
Characteristics
- Assertions enabled - Runtime checks active
- Hot reload enabled - Fast development cycle
- DevTools enabled - Debugging tools available
- Observatory enabled - Performance profiling
- Slow performance - Not optimized
- Large app size - Includes debug symbols
- JIT compilation - Code compiled on-the-fly
When to Use
- Daily development
- Testing features
- Debugging issues
- Using DevTools inspector
How to Run
bash# Default mode flutter run # Explicitly debug flutter run --debug # On specific device flutter run -d <device_id>
Example
dartvoid main() { // Assertions only run in debug mode assert(someCondition, 'This only checks in debug'); // Debug-only code if (kDebugMode) { print('Running in debug mode'); } runApp(MyApp()); }
Debug Banner
dart// Remove debug banner MaterialApp( debugShowCheckedModeBanner: false, // Hide "DEBUG" banner home: HomePage(), )
Release Mode
Purpose: Production deployment (App Store, Play Store)
Characteristics
- Assertions disabled - No runtime checks
- Hot reload disabled - No development tools
- DevTools disabled
- Maximum performance - Fully optimized
- Small app size - No debug symbols
- AOT compilation - Pre-compiled native code
- Tree shaking - Unused code removed
- Obfuscation - Code is minified
When to Use
- Building for production
- App Store/Play Store upload
- Performance testing
- Final user testing
How to Run
bash# Build APK (Android) flutter build apk --release # Build App Bundle (Android - recommended) flutter build appbundle --release # Build iOS flutter build ios --release # Run on device (rare) flutter run --release
Performance
dart// Example: Release mode optimizations void main() { // ❌ This assert is REMOVED in release mode assert(false, 'Never executes in release'); // ✅ This check works in all modes if (someCondition) { throw Exception('Always executes'); } runApp(MyApp()); }
Profile Mode
Purpose: Performance profiling and optimization
Characteristics
- Assertions disabled - Like release
- Performance tracking enabled - Unlike release
- DevTools enabled - For profiling
- Some debugging info - Stack traces available
- Near-release performance - Optimized but with profiling overhead
- No hot reload - Like release
When to Use
- Performance testing
- Finding performance bottlenecks
- Measuring frame rates
- Profiling animations
- Before release build
How to Run
bash# Run in profile mode flutter run --profile # On specific device flutter run --profile -d <device_id> # Build for profile flutter build apk --profile # Android flutter build ios --profile # iOS
Performance Profiling
dartimport 'package:flutter/foundation.dart'; void main() { // Profile mode check if (kProfileMode) { print('Running in profile mode'); } runApp(MyApp()); } // Timeline for profiling import 'dart:developer'; void expensiveOperation() { Timeline.startSync('ExpensiveOperation'); // ... your code ... Timeline.finishSync(); }
Detailed Comparison Table
| Feature | Debug | Profile | Release |
|---|---|---|---|
| Compilation | JIT (Just-In-Time) | AOT (Ahead-Of-Time) | AOT |
| Assertions | ✅ Enabled | ❌ Disabled | ❌ Disabled |
| Hot Reload | ✅ Yes | ❌ No | ❌ No |
| DevTools | ✅ Full access | ✅ Limited (profiling) | ❌ No |
| Performance | Slow (10x slower) | Fast (near-release) | Fastest |
| App Size | Large (~20MB+) | Medium | Small (~5-10MB) |
| Observatory | ✅ Yes | ✅ Yes | ❌ No |
| Debug Banner | ✅ Shows | ❌ Hidden | ❌ Hidden |
| Tree Shaking | ❌ No | ✅ Yes | ✅ Yes |
| Code Obfuscation | ❌ No | ❌ No | ✅ Yes (optional) |
| Use Case | Development | Testing performance | Production |
Build Mode Detection
dartimport 'package:flutter/foundation.dart'; void main() { // Check current mode if (kDebugMode) { print('Debug mode'); } else if (kReleaseMode) { print('Release mode'); } else if (kProfileMode) { print('Profile mode'); } runApp(MyApp()); } // Conditional features class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( // Show debug tools only in debug debugShowCheckedModeBanner: kDebugMode, // Different API endpoints per mode home: HomePage( apiUrl: kReleaseMode ? 'https://api.production.com : 'https://api.staging.com ), ); } }
Performance Comparison
Frame Rate (60 FPS target)
| Mode | Typical FPS | Performance |
|---|---|---|
| Debug | 20-40 FPS | Very slow (10x slower than release) |
| Profile | 55-60 FPS | Near-release performance |
| Release | 60 FPS | Maximum performance |
App Size (Example)
| Mode | APK Size | Notes |
|---|---|---|
| Debug | ~25 MB | Includes debug symbols |
| Profile | ~12 MB | Includes profiling info |
| Release | ~8 MB | Optimized, tree-shaken |
Real-World Examples
Example 1: API Configuration
dartclass ApiConfig { static String get baseUrl { if (kDebugMode) { return 'http://localhost:3000 // Local dev server } else if (kProfileMode) { return 'https://staging-api.example.com } else { return 'https://api.example.com // Production } } }
Example 2: Logging
dartvoid log(String message) { // Only log in debug mode if (kDebugMode) { print('[DEBUG] $message'); } } void main() { log('App started'); // Only prints in debug runApp(MyApp()); }
Example 3: Feature Flags
dartclass FeatureFlags { static bool get showDebugInfo => kDebugMode; static bool get enableAnalytics => kReleaseMode; static bool get useProductionDB => kReleaseMode || kProfileMode; } // Usage if (FeatureFlags.showDebugInfo) { return DebugPanel(); }
Common Pitfalls
❌ Don't Test Performance in Debug Mode
dart// ❌ Bad - testing in debug mode flutter run // Check performance → Will be 10x slower than release! // ✅ Good - test in profile mode flutter run --profile // Check performance → Accurate results
❌ Don't Use Assertions for Production Logic
dart// ❌ Bad - assertion removed in release assert(user != null); user.name; // Crashes in release if user is null! // ✅ Good - proper null check if (user == null) throw Exception('User required');
❌ Don't Submit Debug Builds
bash# ❌ Bad - never submit debug build flutter build apk # Defaults to release, but be explicit # ✅ Good - always explicit flutter build apk --release flutter build appbundle --release
Build Commands Summary
Android
bash# Debug flutter run flutter build apk --debug # Profile flutter run --profile flutter build apk --profile # Release flutter build apk --release # APK (for testing) flutter build appbundle --release # App Bundle (for Play Store)
iOS
bash# Debug flutter run flutter build ios --debug # Profile flutter run --profile flutter build ios --profile # Release flutter build ios --release flutter build ipa --release # For App Store
Web
bash# Debug flutter run -d chrome # Release flutter build web --release
Best Practices
| Practice | Recommendation |
|---|---|
| Development | Always use Debug mode |
| Performance testing | Always use Profile mode |
| Production | Always use Release mode |
| Store submission | Release mode with text |
| API endpoints | Different per mode (dev/staging/prod) |
| Logging | Only in Debug mode |
| Never | Test performance in Debug mode |
Key Takeaways
Debug: Development with hot reload (slow, large size)
Profile: Performance testing (fast, profiling enabled)
Release: Production deployment (fastest, smallest size)
Always test performance in Profile mode, not Debug!