Flutter Analysis and Practice: Design and Practices of the High-Availability Framework

Image for post
Image for post

4.3.1 Why Do We Monitor Flutter Performance?

4.3.2 Required SDKs

4.3.2.1 Performance Metrics

4.3.2.2 SDK Features

4.3.3 Overall Design in Terms of a Single Index

class FpsRecorder extends BaseRecorder {
///...
@override
void onReceivedEvent(BaseEvent event) {
if (event is RouterEvent) {
///...
} 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;
}
} else if (event is UserInputEvent) {
///...
}
}
@override
List<Type> subscribedEventList() {
return <Type>[RenderEvent, RouterEvent, UserInputEvent];
}
}
class FpsProcessor extends BaseProcessor {
///...
@override
void process(BaseData data) {
if (data is FrameData) {
///...
if (isFinishedWithSample(currentTime)) {
///当时间间隔大于1s,则计算一次FPS
_startSampleTime = currentTime;
collectSample(currentTime);
}
}
}
@override
List<Type> subscribedDataList() {
return [FrameData];
}

void collectSample(int finishSampleTime) {
///...
PerformanceDataCenter().push(FpsUploadData(avgFps: fps));
}
///...
}
class MyUploader extends BaseUploader {
@override
List<Type> subscribedDataList() {
return <Type>[
FpsUploadData, //TimeUploadData, ScrollUploadData, ExceptionUploadData,
];
}
@override
void upload(BaseUploadData data) {
if (data is FpsUploadData) {
_sendFPS(data.pageInfoData.pageName, data.avgFps);
}
///...
}
}

4.3.4 Overall Structural Design

Image for post
Image for post
Figure 4–12

4.3.4.1 API

4.3.4.2 Recorder

abstract class BaseRecorder with TimingObserver {
BaseRecorder() {
PerformanceEventCenter().subscribe(this, subscribedEventList());
}
}
mixin TimingObserver {
void onReceivedEvent(BaseEvent event);
List<Type> subscribedEventList();
}

4.3.4.3 Processor

abstract class BaseProcessor{
void process(BaseData data);
List<Type> subscribedDataList(); BaseProcessor(){
PerformanceDataCenter().registerProcessor(this, subscribedDataList());
}
}

4.3.4.4 Uploader

abstract class BaseUploader{  void upload(BaseUploadData data);  List<Type> subscribedDataList();  BaseUploader(){
PerformanceDataCenter().registerUploader(this, subscribedDataList());
}
}

4.3.4.5 PerformanceDataCenter

final Map<Type, Set<BaseProcessor>> _processorMap = <Type, Set<BaseProcessor>>{};final Map<Type, Set<BaseUploader>> _uploaderMap = <Type, Set<BaseUploader>>{};
Image for post
Image for post
Figure 4–13

4.3.4.6 PerformanceEventCenter

4.3.5 Use of the SDK

4.3.6 Implementation of the SDK

Original Source:

Follow me to keep abreast with the latest technology news, industry insights, and developer trends.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store