Dynatrace provides comprehensive app performance monitoring for Flutter applications. This includes tracking app startup times, monitoring navigation between screens, and capturing view-level metrics that help you understand user experience and identify performance bottlenecks.
The app start event is automatically captured by the native OneAgent when your application launches. This event provides insights into how long it takes for your app to become usable.
The native Android and iOS agents automatically capture:
In addition to native metrics, the Dynatrace Flutter plugin captures Flutter-specific timing points during app startup:
| Key | Description |
|---|---|
app_start.flutter.application.pre_plugin_init_start_time | When the Flutter engine begins initializing, triggering the Dynatrace plugin initialization |
app_start.flutter.application.pre_plugin_init_end_time | When the plugin initialization completes |
app_start.flutter.application.main_init_start_time | When the main() function is called and Dynatrace setup begins |
app_start.flutter.application.main_init_end_time | When Dynatrace setup completes and your app is ready to run |
These additional data points help you understand the performance impact of Flutter engine initialization and plugin setup on your overall app startup time.
App start monitoring is enabled by default. No additional configuration is required in your Flutter code—the native agents handle this automatically.
Views represent individual screens of content in your application. Tracking views helps you understand user navigation patterns, identify slow-loading screens, and contextualize errors and performance issues.
Use the startView() method to manually track when a user enters a new screen:
import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';class ProductDetailScreen extends StatefulWidget {@override_ProductDetailScreenState createState() => _ProductDetailScreenState();}class _ProductDetailScreenState extends State<ProductDetailScreen> {@overridevoid initState() {super.initState();Dynatrace().startView('ProductDetail');}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Product Details')),body: Text('Your content here'));}}
Use consistent, meaningful view names across your application. For example: Home, ProductList, ProductDetail, Checkout, OrderConfirmation.
startView() are associated with that view until another view is started.startView() with an empty string are ignored.For applications using Flutter's navigation system, Dynatrace provides DynatraceNavigationObserver to automatically track navigation events.
Add DynatraceNavigationObserver to your MaterialApp or CupertinoApp:
import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';import 'package:flutter/material.dart';void main() {Dynatrace().start(MyFlutterApp());}class MyFlutterApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: 'My App',navigatorObservers: [DynatraceNavigationObserver(),],home: HomeScreen(),);}}
The navigation observer automatically captures:
PageRoute becomes active.paused/inactive), the current view is stopped automatically. On resumed, the previous view is restarted so Dynatrace shows a gap that matches the lifecycle.RouteSettings.name. Routes without a name (or go_router pages lacking name) are skipped to avoid ambiguous entries.For each navigation event, the observer calls startView() with the route name and creates a navigation action (for example, Navigated to screen HomeScreen).
Routes must have a name set via RouteSettings for the observer to track them. Unnamed routes are not reported.
MaterialApp(navigatorObservers: [DynatraceNavigationObserver()],routes: {'/': (context) => HomeScreen(),'/products': (context) => ProductListScreen(),'/product-detail': (context) => ProductDetailScreen(),'/checkout': (context) => CheckoutScreen(),},);
If you're using go_router, add the observer to your router configuration:
import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';import 'package:go_router/go_router.dart';final router = GoRouter(observers: [DynatraceNavigationObserver()],routes: [GoRoute(path: '/',name: 'home',builder: (context, state) => HomeScreen(),),GoRoute(path: '/products',name: 'products',builder: (context, state) => ProductListScreen(),),GoRoute(path: '/product/:id',name: 'product-detail',builder: (context, state) => ProductDetailScreen(id: state.pathParameters['id']!,),),],);
Application Not Responding (ANR) errors occur when the main thread is blocked for too long, causing the app to become unresponsive. Dynatrace automatically captures ANR events.
ANR reporting is enabled by default. To disable it, update your dynatrace.config.yaml.
Android:
android:config:"dynatrace {configurations {defaultConfig {anrReporting false}}}"
iOS:
ios:config:"<key>DTXANRReportingEnabled</key><false/>"
ANR events are only sent if the user restarts the app within 10 minutes of the ANR occurring.