flutter_app_inspector 0.1.0
flutter_app_inspector: ^0.1.0 copied to clipboard
A developer observability and runtime inspection layer for Flutter applications.
β‘ flutter_app_inspector #
A developer observability and runtime inspection layer inside Flutter applications.
flutter_app_inspector provides a lightweight, real-time in-app developer performance HUD overlay designed to help Flutter developers answer critical performance questions:
- Why is my app dropping frames?
- What is the current FPS, average FPS, and frame render duration?
- How many janky frames occurred and what is the jank rate?
- What is the native process memory footprint (RSS) and peak memory usage?
- Where are the performance bottlenecks?
π¨ In-App Developer Overlay #
When running your Flutter application in debug or profile mode, a floating, high-density HUD appears over your normal Flutter UI:
ββββββββββββββββββββββββββββββββββββββββ
β β‘ 58 FPS 16.7 ms 182.4 MB β
ββββββββββββββββββββββββββββββββββββββββ
Tap the compact pill to expand the full inspection HUD card:
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β‘ App Inspector [INFO] π β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Performance Score 92/100 (Good) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β FPS Frame Time β
β 58 16.7 ms β
β Avg 56 | Min 42 Budget 16.7 ms β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Jank Memory β
β 2 frames 182.4 MB β
β Rate 2.4% Peak 241.0 MB β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Frame History (ms) β
β β β β β β β β β β β β β β β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β¨ Features (Phase 1) #
- π Simple Integration: Initialize in
main()with a single line and wrap your app or useMaterialApp(builder: AppInspector.builder). - π Frame & FPS Engine: Monitors FPS (current, average, minimum, maximum) and frame duration (build + raster span).
- β± Dynamic Budget Detection: Automatically detects device refresh rates (60Hz, 90Hz, 120Hz) and computes exact frame budgets (16.67ms, 11.11ms, 8.33ms).
- β‘ Jank Detection: Identifies dropped frames exceeding budget thresholds and logs actionable jank events.
- π§ Native Memory Sampling: Reads process Resident Set Size (RSS) memory using native Dart
ProcessInfo.currentRssAPIs without fake values. - π― Interactive HUD Overlay: Floating, draggable, minimizable/expandable dark developer HUD that passes touch events through to your host application.
- π Bounded Event Store: In-memory ring-buffer store with auto-eviction of oldest events (
DoubleLinkedQueue). - πͺ΅ Throttled Console Output: Configurable stdout logger printing metrics and jank warnings without spamming your terminal.
- π Production Safe: Disabled by default in release builds (
kDebugMode || kProfileMode). Defensive error isolation ensures monitoring logic never crashes host app.
π¦ Installation #
Add flutter_app_inspector to your pubspec.yaml:
dependencies:
flutter_app_inspector: ^0.1.0
Or run:
flutter pub add flutter_app_inspector
π Quick Start #
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app_inspector/flutter_app_inspector.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
// 1. Initialize inspector
AppInspector.initialize(
config: AppInspectorConfig(
enabled: kDebugMode || kProfileMode,
consoleLogging: true,
),
);
runApp(
// 2. Wrap root application with inspector overlay
AppInspectorOverlay(
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Flutter App',
home: const HomeScreen(),
);
}
}
Alternative Builder API #
If you prefer using MaterialApp.builder:
MaterialApp(
builder: AppInspector.builder,
home: const HomeScreen(),
);
βοΈ Configuration #
Customize behavior using AppInspectorConfig:
AppInspector.initialize(
config: AppInspectorConfig(
enabled: kDebugMode,
showOverlay: true,
frameMonitoring: true,
memoryMonitoring: true,
consoleLogging: true,
logLevel: InspectorLogLevel.info,
overlayMode: InspectorOverlayMode.compact,
overlayPosition: InspectorOverlayPosition.topRight,
refreshInterval: Duration(milliseconds: 500),
maxEvents: 500,
maxFrameHistory: 120,
jankThresholdMultiplier: 1.2,
),
);
β± Custom Operation & Network Tracking #
Measure custom blocks of code or network latency using built-in extension points:
// Custom operation measurement
await AppInspector.measure('Database Migration', () async {
await runDatabaseMigration();
});
// Manual tracker control
final tracker = AppInspector.start('Checkout Processing');
await processCheckout();
tracker.stop();
// Generic network request tracking
final netTracker = AppInspector.startNetworkRequest(
method: 'GET',
url: '/api/v1/products',
);
final response = await http.get(Uri.parse('https://api.example.com/products'));
netTracker.complete(
statusCode: response.statusCode,
responseSize: response.bodyBytes.length,
);
π§© Widget Rebuild Inspector #
Track widget rebuild counts, frequencies, build durations, and surge spikes safely using public Flutter APIs:
// 1. Wrap any widget tree to measure rebuilds & build durations
InspectorWidgetTracker(
name: 'ProductList',
child: const ProductListWidget(),
)
// 2. Or use WidgetRebuildMixin in StatefulWidget State classes
class ProductCardState extends State<ProductCard> with WidgetRebuildMixin {
@override
Widget buildWidget(BuildContext context) {
return Card(child: Text('Product Item'));
}
}
The expanded HUD card tracks detailed per-widget build performance:
- Rebuilds: Total build pass count
- Average Build: Mean duration per build pass
- Maximum Build: Peak build pass duration
- Total Build: Cumulative time spent building widget
It automatically flags β οΈ Potential Slow Widgets when maximum build durations exceed target frame budgets (e.g. >16.7ms), highlighting potential optimization opportunities without falsely claiming guaranteed root causes.
πΊοΈ Navigation Performance Monitor #
Track route transitions (push, pop, replace), transition durations, and first frame rendering times by adding AppInspector.navigatorObserver to your app:
MaterialApp(
title: 'My Application',
navigatorObservers: [
AppInspector.navigatorObserver,
],
home: const HomeScreen(),
)
The HUD overlay records transition durations (e.g. Home β Products (112ms)) and highlights β οΈ Slow Route Transitions when transition times exceed configurable thresholds (slowNavigationThreshold, default 200ms).
πΌοΈ Image Performance Monitor #
Track image loading durations, cache hit rates, load failures, raw vs. displayed image dimensions, and estimated decoded memory footprints:
InspectorImageTracker(
urlOrKey: 'https://example.com/large_product.jpg',
imageProvider: NetworkImage('https://example.com/large_product.jpg'),
child: Image.network('https://example.com/large_product.jpg'),
)
Key Features #
- Cache Hit Rate: Tracks real-time cache hit/miss percentages and global Flutter
ImageCachestats (PaintingBinding.instance.imageCache). - Estimated Decoded Memory: Calculates decoded RAM footprint (
width * height * 4 bytesfor 32-bit RGBA). Memory numbers are explicitly marked as estimated (~X.X MB). - β οΈ Large Image Alerts: Automatically detects when raw image dimensions significantly exceed rendered layout bounds (or threshold ratio) and suggests
cacheWidth/cacheHeightoptimizations.
π¨ Error & Exception Monitor #
Track, group, and analyze development-time Flutter framework errors and unhandled exceptions:
// Safely chain onto FlutterError.onError and PlatformDispatcher.instance.onError
AppInspector.attachErrorHandlers();
// Or manually record custom try-catch exceptions
try {
fetchData();
} catch (e, stackTrace) {
AppInspector.recordError(e, stackTrace: stackTrace);
}
Key Features #
- Error Grouping: Automatically groups exceptions by runtime class type (
StateError,SocketException,FlutterError), tracking total count, first occurrence, and last occurrence. - β οΈ Repeated Error Alerts: Identifies error surges meeting repeated thresholds (e.g. 5+ occurrences) and displays time-elapsed context ("Occurrences: 27, Last occurrence: 2 seconds ago").
- Sanitized Stack Traces: Truncates stack traces to top frame summaries in memory to eliminate unbounded memory growth.
π "Why Is My App Slow?" Analysis Engine #
Perform comprehensive developer-focused diagnostic analysis across frames, jank, widget rebuilds, network requests, memory footprints, image decoding, route transitions, startup timing, errors, and custom operation timers:
final report = AppInspector.analyzePerformance();
print(report.formattedSummary);
Example Report Output: #
Performance Score: 71/100
Top Issues
π΄ Heavy frame rendering
π ProductList rebuild hotspot
π Slow /products API
π‘ Large image detected
Recommended Priority
1. Investigate ProductList rebuilds
2. Investigate /products latency
3. Optimize image loading
Key Features #
- Evidence-Backed Recommendations: Recommendations are generated strictly when supported by empirical metric evidence.
- Cross-Metric Correlation Engine: Identifies temporal correlations (e.g. jank frame rendering coinciding with a widget rebuild spike or oversized image load).
π Performance Health Dashboard & Dynamic Scoring #
The expanded developer HUD functions as a full Performance Health Dashboard:
- 9 Category Scores: Evaluates FPS, Jank, Frame Time, Memory, Widgets, Network, Images, Startup, and Errors.
- Zero Penalization Dynamic Weighting: Category scores contribute to the aggregate overall score only when real measurements exist. Missing, disabled, or unsupported monitors (e.g., Memory RSS on Web browsers) are dynamically excluded from the score denominator, preventing unfair point deductions.
- Category Health Status Chips: Live HUD status chips displaying
FPS: 60,Jank: 0%,Memory: 142MB,Errors: 0orN/A. - Recent Event Feed: Real-time scrolling feed of recorded inspector events.
- Performance Trends Visualizer: Sparkline timeline graph for frame rendering budget history and RSS memory growth.
π§ Platform Memory Limitations #
- Desktop / Mobile (Android, iOS, macOS, Windows, Linux): Reads actual native process Resident Set Size (RSS) memory in megabytes via
dart:io ProcessInfo.currentRss. - Web Target: Process RSS memory is not exposed by web browsers. The inspector displays
N/Awith clear documentation rather than fabricating numbers.
πΊ Roadmap #
- Phase 2: Widget rebuild tracking hotspots, generic network interceptors, route navigation timing, image memory analyzer.
- Phase 3: Full-screen DevTools dashboard, unified event timeline, session recording, HTML/JSON report exports.
- Phase 4: Dio, package:http, BLoC, Riverpod, and Provider adapters.
- Phase 5: CI/CD performance regression detection & historical session comparison.
π License #
MIT License. See LICENSE for details.