# How to Track the Performance of Your FlutterFlow App

- Tool: FlutterFlow
- Difficulty: Beginner
- Time required: 30-40 min
- Compatibility: FlutterFlow Free+ (Performance Monitoring SDK); full dashboard features on any Firebase plan
- Last updated: March 2026

## TL;DR

Track your FlutterFlow app's performance by enabling Firebase Performance Monitoring (automatic app start and screen render traces), adding custom traces around your slowest operations via a Custom Action, and monitoring Crashlytics for crash-free user rate. The critical mistake is testing only in FlutterFlow's Run Mode on a fast desktop connection — real users on 3G with budget Android phones see completely different performance numbers.

## What Firebase Performance Monitoring Measures

Firebase Performance Monitoring automatically measures three things the moment you enable it: app start time (from launch to first interactive frame), screen render time (frame rate per page), and network request latency (how long HTTP calls take). These automatic traces cover most of what you need. For custom workflows — like the time it takes to load a user's feed, process a payment, or render a chart — you add custom traces using the Performance SDK in a FlutterFlow Custom Action. All data is split by device, OS, country, and app version in the Firebase Console, making it easy to see that your app is fast on iOS but slow on Android 10.

## Before you start

- FlutterFlow project with Firebase connected
- Firebase Performance Monitoring package added to your FlutterFlow project (firebase_performance)
- App published or in Test Flight/internal testing — Run Mode performance is not representative
- Firebase Analytics enabled (Performance Monitoring uses the same data pipeline)

## Step-by-step guide

### 1. Enable the Firebase Performance Monitoring package

In FlutterFlow go to Settings > Flutter Packages and add firebase_performance at the latest version. This package is separate from firebase_core and must be added explicitly. After adding it, go to your main.dart initialization (Custom Code > main function if you have one, or FlutterFlow's Firebase initialization flow) and confirm that Firebase is initialized before the app runs. Performance Monitoring auto-initializes when the package is present — no additional code is needed for automatic traces. Rebuild your app in Test Mode to confirm there are no package conflicts.

**Expected result:** The firebase_performance package is in your project's dependencies and Performance Monitoring shows 'Connected' in Firebase Console.

### 2. Interpret automatic traces in the Firebase Console

Navigate to Firebase Console > Performance > Dashboard. The Traces table shows three automatic trace types: _app_start (time from cold launch to first frame), _st_{PageName} (screen render per page), and network traces for every HTTP call your app makes. Click on _app_start and view the duration percentile distribution. The p50 (median) should be under 2 seconds; p95 should be under 5 seconds. Click on a specific page's screen trace and look for the 'Slow/Frozen frames' rate — above 1% slow frames means users are experiencing jank. Use the filters at the top to segment by device model, OS version, and country to pinpoint where performance is worst.

**Expected result:** You can identify your three slowest screens and the device/OS combinations where performance is worst.

### 3. Add a custom trace around your heaviest operation

Automatic traces don't tell you why a screen is slow — just that it is. Add a custom trace to instrument your most complex operation. In FlutterFlow create a Custom Action called startPerfTrace and another called stopPerfTrace. The start action creates a named trace and starts it; the stop action stops it and records the duration to Firebase. Wrap these around your most expensive flow, such as loading a personalized feed, processing an image, or running a multi-step form submission. In the Firebase Console, your custom trace appears under Performance > Custom Traces with the same distribution and segmentation views as automatic traces.

```
// Custom Action: perfTrace.dart
import 'package:firebase_performance/firebase_performance.dart';

// Store active traces — keyed by name
final Map<String, Trace> _activeTraces = {};

Future startPerfTrace(String traceName) async {
  final trace = FirebasePerformance.instance.newTrace(traceName);
  await trace.start();
  _activeTraces[traceName] = trace;
}

Future stopPerfTrace(String traceName) async {
  final trace = _activeTraces[traceName];
  if (trace != null) {
    await trace.stop();
    _activeTraces.remove(traceName);
  }
}

// Add custom metric to an active trace
Future addTraceMetric(
    String traceName, String metricName, int value) async {
  _activeTraces[traceName]?.setMetric(metricName, value);
}
```

**Expected result:** Custom trace durations appear in Firebase Console > Performance > Custom Traces within 24 hours of real device usage.

### 4. Monitor Crashlytics alongside Performance for a full health picture

Performance Monitoring tells you about slowness; Crashlytics tells you about crashes. Both together give you a complete app health view. In Firebase Console open Crashlytics and check three metrics: crash-free users rate (should be above 99.5% for a healthy app), crash count trend over the last 30 days, and affected users per issue. Click each issue to see the stack trace, affected device models, and the app version that introduced it. For performance-related crashes (out-of-memory, ANR — Application Not Responding), you will see them in both Crashlytics and as spikes in the Performance > Slow/Frozen frames view. Set up Crashlytics Velocity Alerts to receive an email when a new crash type affects more than 0.1% of your users in one hour.

**Expected result:** You have a baseline crash-free rate and the top crash types identified and prioritized.

### 5. Set up performance regression alerts

Firebase Performance Monitoring supports threshold alerts that fire when a metric crosses a value you define. Go to Firebase Console > Performance > Alerts and create a new alert. Select the trace (e.g., _app_start), choose the metric (duration p90), set the threshold (e.g., alert when > 4000ms), and add your email. Create alerts for your three most critical traces: app start time, your highest-traffic screen, and your main Cloud Function's HTTP response time. Also go to Firebase Console > Functions > Dashboard and check the 95th percentile execution time for each Cloud Function. Functions taking more than 5 seconds regularly indicate a query or external API call that needs optimization.

**Expected result:** You receive email notifications when app start time or key trace durations exceed your defined thresholds.

## Complete code example

File: `perfTrace.dart`

```dart
// Custom Actions for Firebase Performance Monitoring
// Add firebase_performance to your FlutterFlow packages
import 'package:firebase_performance/firebase_performance.dart';

// In-memory store for active traces (single session scope)
final Map<String, Trace> _activeTraces = {};

/// Start a named performance trace
Future<void> startPerfTrace(String traceName) async {
  try {
    final trace = FirebasePerformance.instance.newTrace(traceName);
    await trace.start();
    _activeTraces[traceName] = trace;
  } catch (e) {
    // Fail silently — performance tracking should never crash the app
    debugPrint('PerfTrace start error: $e');
  }
}

/// Stop a named performance trace and record it
Future<void> stopPerfTrace(String traceName) async {
  try {
    final trace = _activeTraces[traceName];
    if (trace != null) {
      await trace.stop();
      _activeTraces.remove(traceName);
    }
  } catch (e) {
    debugPrint('PerfTrace stop error: $e');
  }
}

/// Add a custom integer metric to an active trace
/// (e.g., number of items loaded, bytes downloaded)
Future<void> addTraceMetric(
    String traceName, String metricName, int value) async {
  try {
    _activeTraces[traceName]?.setMetric(metricName, value);
  } catch (e) {
    debugPrint('PerfTrace metric error: $e');
  }
}

/// Add a custom attribute to an active trace
/// (e.g., user segment, feature flag value)
Future<void> addTraceAttribute(
    String traceName, String key, String value) async {
  try {
    _activeTraces[traceName]?.putAttribute(key, value);
  } catch (e) {
    debugPrint('PerfTrace attribute error: $e');
  }
}
```

## Common mistakes

- **Only checking performance in Run Mode on a fast WiFi connection** — FlutterFlow's Run Mode runs in a browser on your local machine, which is not representative of a real mobile device. Your p50 app start time in Run Mode might be 0.5 seconds; on a real 3G Android it could be 8 seconds. Fix: Always test performance on a real physical device, preferably a mid-range Android (not your development iPhone). Use Firebase Performance Monitoring data from real users as the authoritative source.
- **Adding performance traces inside widget build methods** — Flutter rebuilds widgets frequently. A trace placed in a build method starts and stops dozens of times per second, polluting your data with noise. Fix: Place traces around user-initiated operations in action flows (button taps, page loads), not in widget constructors or build methods.
- **Ignoring the p95 metric and only looking at p50 (median)** — The median hides performance problems affecting your worst-performing 5%. If p95 app start is 12 seconds, 1 in 20 users quits before your app loads. Fix: Always review p95 alongside p50. Your optimization target should be bringing p95 down, not improving the median of already-fast users.

## Best practices

- Treat your app start time p90 as a product KPI — track it in your analytics dashboard and alert on regressions after every release.
- Wrap every Cloud Function call from FlutterFlow with a custom trace so you can see end-to-end latency including network time, not just server execution time.
- Segment performance data by app version in the Firebase Console to immediately identify which release caused a regression.
- Test on at least three device classes: a flagship phone, a 3-year-old mid-range Android, and a tablet — they will have very different performance profiles.
- Keep your Firestore queries paginated with a page size of 20-50 items. Loading 500 documents into a list on a slow connection is the single most common performance killer in FlutterFlow apps.
- Use Firebase Performance network traces to identify which API endpoints are slow — sometimes a third-party API is the bottleneck, not your app code.
- Review Cloud Function cold start times in Performance data. If cold starts are frequent, consider minimum instances to keep functions warm for high-traffic endpoints.

## Frequently asked questions

### How long does it take for Performance Monitoring data to appear in the Firebase Console?

Automatic traces from real devices typically appear within 12-24 hours of the first session. Custom traces follow the same pipeline. The Realtime tab in Firebase Console shows data within a few minutes, but the main dashboard aggregates over a longer window.

### Can I see performance data from FlutterFlow's Test Mode?

Test Mode runs in a browser on your machine and is not a representative environment for performance data. The performance numbers you see in Test Mode reflect your development hardware and network, not your users' devices. Use internal distribution (TestFlight, Firebase App Distribution) to test on real devices.

### What is a good app start time target?

Aim for under 2 seconds at p50 and under 4 seconds at p95 for a cold start. Warm starts (app already in memory) should be under 1 second. If your app start p90 is above 5 seconds, investigate what is running in your On App Load actions.

### How do I measure Firestore query performance specifically?

Wrap your Firestore query in a custom trace: call startPerfTrace before the query action in FlutterFlow and stopPerfTrace after the result is returned. You can also add a metric for the number of documents returned. This gives you query-specific latency data in the Firebase Console.

### Is Firebase Performance Monitoring free?

Yes. Performance Monitoring is included at no cost on both the Spark (free) and Blaze plans. There are no per-event charges for performance data. The only costs are indirect — if performance monitoring drives you to increase Firebase Function invocations, those are billed normally.

### Can I track performance for specific user segments?

Yes, via custom trace attributes. Call addTraceAttribute with a key like 'user_segment' and the user's segment value before stopping the trace. You can then filter performance data by this attribute in the Firebase Console's custom traces view.

---

Source: https://www.rapidevelopers.com/flutterflow-tutorials/how-can-i-track-the-performance-of-my-flutterflow-app
© RapidDev — https://www.rapidevelopers.com/flutterflow-tutorials/how-can-i-track-the-performance-of-my-flutterflow-app
