網(wǎng)站后臺信息維護(hù)要怎么做網(wǎng)站模板平臺資源
????????1. 頁面異常監(jiān)測
? ? ? ? ?在Flutter中,通常用FlutterError監(jiān)測Flutter框架拋出的異常,用runZonedGuarded監(jiān)測應(yīng)用中用戶代碼異常。
? ? ? ? ? ??
class AppGuarded {run(Widget app) {//1. 用FlutterError監(jiān)測flutter框架拋出的異常FlutterError.onError = (FlutterErrorDetails details) async {//線上環(huán)境,將異常交給zone統(tǒng)一處理if (kReleaseMode) {Zone.current.handleUncaughtError(details.exception, details.stack!);} else {//開發(fā)期間,走Console拋出FlutterError.dumpErrorToConsole(details);}};//2. runZonedGuarded監(jiān)測整個用應(yīng)用代碼異常 不使用FlutterError默認(rèn)只能捕捉業(yè)務(wù)代碼異常runZonedGuarded(() {runApp(app);}, (e, s) => _reportError(e, s));}///通過接口上報異常_reportError(Object error, StackTrace s) {print('kReleaseMode:$kReleaseMode');print('catch error:$error');}
}
????????2. 監(jiān)測頁面流暢性(幀率)
????????幀率監(jiān)測在Flutter中通常通過在SchedulerBinding中注冊fps相關(guān)回調(diào)來實現(xiàn)。通常需要保留最近若干個FrameTiming的總耗時,計算其平均值,以消除不必要數(shù)據(jù)波動。
void start() {SchedulerBinding.instance.addTimingsCallback(_onReportTimings);
}
// 不需監(jiān)聽時移除
void stop() {SchedulerBinding.instance.removeTimingsCallback(_onReportTimings);
}
void _onReportTimings(List<FrameTiming> timings) {// TODO
}
?????????3. 頁面顯示耗時(FCP)
? ? ? ? ?記錄頁面初始化和首次上屏?xí)r間,然后計算其時間差即可。
@overrideinitState() {super.initState();//1. 記錄頁面創(chuàng)建時間double startTime = time(0);//2.注冊首幀顯示時間回調(diào)WidgetsBinding.instance.addPostFrameCallback((timeStamp) {double endTime = time(0);print('WidgetsBinding Test-${(context as Element).size}');});
? ? ? ? 4.?頁面PV監(jiān)測
? ? ? ? 頁面PV監(jiān)測核心是檢測到頁面棧的變化,以便統(tǒng)計出頁面曝光次數(shù)。如果應(yīng)用采用自定義導(dǎo)航框架,只需在導(dǎo)航框架正確位置添加埋點即可。若采用的是系統(tǒng)默認(rèn)的導(dǎo)航框架,則可通過繼承NavigatorObserver,捕獲Navigator的didPush和didPop回調(diào)。
//導(dǎo)航棧的變化監(jiān)聽
class MyNavigator extends NavigatorObserver{@overridevoid didPop(Route<dynamic> route, Route<dynamic> previousRoute) {super.didPop(route, previousRoute);var previousName = '';if (previousRoute == null) {previousName = 'null';}else {previousName = previousRoute.settings.name;}print('YM----->NavObserverDidPop--Current:' + route.settings.name + ' Previous:' + previousName);}@overridevoid didPush(Route<dynamic> route, Route<dynamic> previousRoute) {super.didPush(route, previousRoute);var previousName = '';if (previousRoute == null) {previousName = 'null';}else {previousName = previousRoute.settings.name;}print('YM-------NavObserverDidPush-Current:' + route.settings.name + ' Previous:' + previousName);}