4. Performance & Optimization

Performance Metrics

Code Minification Enabled0 / 100
Resource Shrinking Enabled0 / 100
Asset Optimization30 / 100
Memory Management60 / 100

4.1 App Size & Bundle Analysis

Status: Fail

Findings:

  • Code obfuscation disabled: minifyEnabled and shrinkResources not configured in Android release builds - significantly increases app size
  • ProGuard rules exist but unused: ProGuard rules file exists (proguard-rules.pro) but not used since minification is disabled
  • Unoptimized assets: Images stored as PNG/JPEG without compression optimization
  • No asset optimization: No evidence of image compression, WebP conversion, or asset optimization
  • Multiple image resolutions: Images provided in 1.0x, 2.0x, 3.0x resolutions (good practice) but files may not be optimized
  • Large asset directory: Extensive asset list with multiple resolution variants

Evidence:

  • android/app/build.gradle: No minifyEnabled or shrinkResources in release build type (lines 93-100)
  • android/app/proguard-rules.pro: ProGuard rules exist but not used
  • pubspec.yaml assets section (lines 125-167): Extensive image list without optimization
  • Assets directory contains PNG/JPEG files: background.png, logo-normal.png, gulf_logo.png, for_you.png, gulf_tankstations.png, arrow.png, arrow_white.png, arrow_orange.png, favorite_station_bg.png, super_game_bg.png
  • Multiple resolution folders: 1.0x/, 2.0x/, 3.0x/ for images (good practice)
  • No WebP conversion or image compression tools in use

Risk Level: High Risk

Recommendation:

  • Immediate actions:
  • Enable code obfuscation and minification for release builds (minifyEnabled true, shrinkResources true)
  • Analyze bundle size using flutter build appbundle --analyze-size or flutter build apk --analyze-size
  • Optimize images (compress PNGs, convert to WebP where appropriate)
  • Remove unused assets and resources
  • Short-term:
  • Use image optimization tools (e.g., flutter_image_compress)
  • Review and remove unused dependencies
  • Consider lazy loading for large assets
  • Enable ProGuard/R8 with proper rules

4.2 Memory Management

Status: ⚠️Warning

Findings:

  • Image memory usage: Image.memory() used for loading images from bytes without size limits or caching strategy
  • Some dispose methods implemented: Some routes properly implement dispose() (e.g., camera_route.dart, video_route.dart)
  • No memory leak detection: No evidence of memory profiling or leak detection tools
  • Large image loading: Images loaded into memory as Uint8List without size validation
  • State persistence: State saved to database on every change, potential performance impact
  • Multiple state classes persist to database: Both SessionState and UserLoyaltyState save to database on every setter call

Evidence:

  • lib/widgets/mobile_content_image.dart: Image.memory() usage without size limits (lines 27-31)
  • lib/widgets/layouts/button_widget_layout.dart: Image.memory() usage (line 46)
  • lib/routes/camera_route.dart: Proper dispose implementation for camera controller (lines 52-57)
  • lib/routes/video_route.dart: Proper dispose implementation (lines 43-48)
  • lib/states/session_state.dart: State saved to database on every setter call (lines 63-123) - potential performance issue
  • lib/states/user_loyalty_state.dart: State saved to database on every setter call (lines 93-156) - potential performance issue

Risk Level: Medium Risk

Recommendation:

  • Immediate actions:
  • Add memory limits for image loading (validate image size before loading)
  • Implement proper image caching strategy
  • Review all dispose methods for completeness
  • Short-term:
  • Add memory profiling to identify leaks
  • Implement image size validation before loading
  • Use image caching library (e.g., cached_network_image for network images)
  • Optimize database write operations (batch updates instead of per-change writes)
  • Consider using Image.asset() instead of Image.memory() where possible

4.3 Network Performance

Status: ⚠️Warning

Findings:

  • Firebase Performance monitoring implemented: Performance traces added to routes and Dio interceptor for network monitoring
  • Timeout configuration: Network timeouts set to 30 seconds for connect, 20 seconds for receive (connect timeout may be too long for some operations)
  • No request caching: No evidence of HTTP response caching or request deduplication
  • No request batching: Multiple individual API calls instead of batched requests where possible
  • Token refresh creates new Dio instance: Token refresh creates separate Dio client, potential overhead
  • No request retry logic: No automatic retry mechanism for failed network requests
  • Firebase Performance interceptor: Dio interceptor properly configured for performance monitoring

Evidence:

  • lib/singletons/dio_singleton.dart lines 23-24: Timeout configuration (30 seconds for connect, 20 seconds for receive)
  • lib/singletons/dio_singleton.dart lines 27-28: Firebase Performance interceptor added to Dio
  • lib/singletons/dio_singleton.dart lines 84-85: New Dio instance created for token refresh (overhead)
  • Multiple routes with Firebase Performance tracing:
    • lib/routes/login_route.dart (lines 49-54)
    • lib/routes/generic_route.dart (lines 35-40)
    • lib/routes/camera_route.dart (lines 43-48)
    • lib/routes/register_route.dart (line 40)
    • lib/routes/register_data_route.dart (line 43)
    • lib/routes/save_gulf_route.dart (line 32)
    • lib/routes/video_route.dart (line 24)
    • And potentially more routes with similar tracing
  • No HTTP cache implementation found
  • No request batching or queuing mechanism
  • No retry logic in error handlers

Risk Level: Medium Risk

Recommendation:

  • Immediate actions:
  • Consider reducing connect timeout from 30 seconds to 20 seconds for better user experience
  • Implement HTTP response caching for static/rarely-changing data
  • Add request retry logic for transient failures
  • Optimize token refresh to reuse existing Dio instance where possible
  • Short-term:
  • Implement request deduplication for identical concurrent requests
  • Add request prioritization for critical operations
  • Batch related API calls where possible
  • Review Firebase Performance traces to identify slow endpoints

4.4 Battery & Resource Usage

Status: ⚠️Warning

Findings:

  • Location services: OneSignal location permission requested (OneSignal.Location.requestPermission()) - location sharing may be enabled
  • Connectivity monitoring: Connectivity state managed without continuous stream subscription (good practice)
  • Camera usage: Camera resources properly disposed in camera_route.dart
  • Firebase services: Multiple Firebase services initialized (Core, Messaging, Crashlytics, Performance, Analytics)
  • OneSignal initialized: OneSignal push notifications initialized with verbose logging enabled

Evidence:

  • lib/main_prod.dart line 17: OneSignal.Location.requestPermission() - location permission requested (may share location)
  • lib/main_staging.dart line 20: OneSignal.Location.requestPermission() - location permission requested
  • lib/main_prod.dart line 15: OneSignal.Debug.setLogLevel(OSLogLevel.verbose) - verbose logging enabled (may impact performance)
  • lib/states/connectivity_status.dart: Simple state management without continuous stream subscription
  • lib/routes/camera_route.dart: Camera properly disposed (lines 52-57)
  • lib/main_prod.dart line 21: Firebase services initialized (Core, Messaging, Crashlytics, Performance, Analytics)

Risk Level: Medium Risk

Recommendation:

  • Immediate actions:
  • Review OneSignal location sharing settings - consider disabling location sharing if not needed
  • Disable verbose logging in production builds (OSLogLevel.none or OSLogLevel.error)
  • Continue monitoring battery usage in production
  • Short-term:
  • Review Firebase service usage and disable unused services if any
  • Implement efficient push notification handling
  • Monitor location service usage patterns
  • Use location services only when needed (not continuously)