Mobile Development 11 min read

Why Flutter Performance Monitoring Is Needed and SDK Design Overview

To overcome native APM’s inability to monitor Flutter pages, the team created a high‑availability, open‑source Flutter SDK that records smoothness, load time, and exceptions through a four‑layer, publish‑subscribe architecture—API, Recorder, Processor, and Uploader—offering accurate, low‑overhead, extensible performance data for integration and future enhancements.

Xianyu Technology
Xianyu Technology
Xianyu Technology
Why Flutter Performance Monitoring Is Needed and SDK Design Overview

Mobile APM is a mature topic in the native world, but most native monitoring SDKs become ineffective on Flutter pages due to Flutter’s revolutionary architecture. To bridge this gap, the team launched a high‑availability Flutter SDK that enables Flutter pages to be measured just like native pages.

What the SDK Should Achieve

Two key questions were addressed: which performance metrics to collect and what characteristics the SDK must have.

Performance Metrics

1. Page smoothness – besides FPS, the SDK records scroll duration and jank duration to differentiate minor and severe stutters. 2. Page load time – the SDK uses “time to interactive” (TTI), i.e., the interval from a navigation request to the moment the page becomes interactive. 3. Exceptions – captured directly.

SDK Features

1. Accuracy – false positives/negatives must be avoided. 2. Low overhead – data collection should not degrade app performance. 3. Extensibility – the open‑source SDK should be easy to extend with clear conventions.

Overall Architecture

The SDK is divided into four layers, connected via two singleton centers using a publish‑subscribe model, which decouples each layer and makes data flow flexible.

API Layer

Exposes methods such as init() (called before runApp()) and pushEvent() for the business side to provide timing events.

Recorder Layer

Collects raw data from events. Example implementation of a FPS recorder:

class FpsRecorder extends BaseRecorder {
  @override
  void onReceivedEvent(BaseEvent event) {
    if (event is RouterEvent) {
      // handle router event
    } else if (event is RenderEvent) {
      switch (event.eventType) {
        case RenderEventType.beginFrame:
          _frameStopwatch.reset();
          _frameStopwatch.start();
          break;
        case RenderEventType.endFrame:
          _frameStopwatch.stop();
          PerformanceDataCenter().push(FrameData(_frameStopwatch.elapsedMicroseconds));
          break;
      }
    }
  }

  @override
  List<Type> subscribedEventList() => [RenderEvent, RouterEvent, UserInputEvent];
}

Processor Layer

Transforms raw data into uploadable data. Example FPS processor:

class FpsProcessor extends BaseProcessor {
  @override
  List<Type> subscribedDataList() => [FrameData];

  @override
  void process(BaseData data) {
    if (data is FrameData) {
      // calculate instantaneous FPS over 1‑second windows
      // push FpsUploadData to PerformanceDataCenter
    }
  }
}

Uploader Layer

Implemented by the app developer to send processed data to a backend. Example uploader:

class MyUploader extends BaseUploader {
  @override
  List<Type> subscribedDataList() => [FpsUploadData];

  @override
  void upload(BaseUploadData data) {
    if (data is FpsUploadData) {
      _sendFPS(data.pageInfoData.pageName, data.avgFps);
    }
  }
}

The two singleton centers manage subscriptions:

class PerformanceDataCenter {
  final Map<Type, Set<BaseProcessor>> _processorMap = {};
  final Map<Type, Set<BaseUploader>> _uploaderMap = {};

  void push(BaseData data) {
    // dispatch to processors and uploaders based on data type
  }

  void registerProcessor(BaseProcessor processor, List<Type> types) {
    // add processor to _processorMap
  }

  void registerUploader(BaseUploader uploader, List<Type> types) {
    // add uploader to _uploaderMap
  }
}

Usage steps for SDK consumers:

Add the high‑availability SDK dependency in pubspec.yaml.

Call init() before runApp() to initialize the SDK.

Use pushEvent() in business code to report navigation events (pop/push) and other relevant moments.

Implement a custom Uploader to forward data to your analytics platform.

The SDK has been running stably in the Xianyu product for several months, with continuous accuracy tuning and a recent major refactor. Open‑source release is planned within two months, along with documentation and test cases.

Future work includes adding memory analysis and stack‑trace capture for jank events, and the team invites contributions via pull requests.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

FlutterSDKAPMMobileDevelopmentPerformanceMonitoringPublishSubscribe
Xianyu Technology
Written by

Xianyu Technology

Official account of the Xianyu technology team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.