如何做网站新手,九江市建设工程门户网站,福州市住房和城乡建设部网站,怎么做网站弄网盟背景
闲鱼客户端的flutter页面已经服务上亿级用户#xff0c;这个时候Flutter页面的用户体验尤其重要#xff0c;完善Flutter性能稳定性监控体系#xff0c;可以及早发现线上性能问题#xff0c;也可以作为用户体验提升的衡量标准。那么Flutter的性能到底如何#xff1f;…背景
闲鱼客户端的flutter页面已经服务上亿级用户这个时候Flutter页面的用户体验尤其重要完善Flutter性能稳定性监控体系可以及早发现线上性能问题也可以作为用户体验提升的衡量标准。那么Flutter的性能到底如何是否像官方宣传的那么丝滑Native的性能指标是否可以用来检测Flutter页面下面给大家分享我们在实践中总结出来的Flutter的性能稳定性监控方案。
目标
过度的丢帧从视觉上会出现卡顿现象体现在用户滑动操作不流畅页面加载耗时过长容易中断操作流程Flutter部分exception会导致发生异常代码后面的逻辑没有走到从而造成逻辑bug甚至白屏。这些问题很容易考验用户耐心引起用户反感。
所以我们制定以下三个指标作为线上Flutter性能稳定性标准
页面滑动流畅度页面加载耗时首屏时长可交互时长Exception率
最终目标是让这些数据指标驱动Flutter用户体验升级。
页面滑动流畅度
我们先大概了解下屏幕渲染流程CPU先把UI对象转变GPU可以识别的信息存储进displaylist列表GPU执行绘图指令来执行displaylist取出相应的图元信息进行栅格化渲染显示到屏幕上这样一个循环的过程实现屏幕刷新。
闲鱼客户端采用的Native、Flutter混合技术方案Native页面FPS监控采用集团高可用方案Flutter页面是否可以直接采用这套方案监控
普遍的FPS检测方案Android端采用的是Choreographer.FrameCallBackIOS采用的是CADisplayLink注册的回调原理是类似的在每次发出Vsync信号并且CPU开始计算的时候执行到对应的回调这个时候表示屏幕开始一次刷新计算固定时间内屏幕渲染次数来得到fps。(这种方式只能检测到CPU卡顿对于GPU的卡顿是无法监控到的)。由于这两种方法都是在主线程做检测处理而flutter的屏幕绘制是在UI TaskRunner中进行真正的渲染操作是在GPU TaskRunner中关于详细的Flutter线程问题可以参考闲鱼之前的文章深入理解Flutter引擎线程模式。
这里我们得出结论Native的FPS检测方法并不适用于Flutter。
Flutter官方给我们提供了 Performance Overlay (具体参考 Flutter performance profiling) 作为检测帧率工具可否直接拿来用 上图显示了Performance Overlay模式下的帧率统计可以看到Flutter分开计算GPU 和UI TaskRunner。UI Task Runner被Flutter Engine用于执行Dart root isolate代码GPU Task Runner被用于执行设备GPU的相关调用。通过对flutter engine源码分析UI frame time是执行window.onBeginFrame所花费的总时间。GPU frame time是处理CPU命令转换为GPU命令并发送给GPU所花费的时间。
这种方式只能在debug和profile模式下开启没有办法作为线上版本的fps统计。但是我们可以通过这种方式获得启发通过监听Flutter页面刷新回调方法handleBeginFrame()、handleDrawFrame()来计算实际FPS。
具体实现方式
注册WidgetsFlutterBinding监听页面刷新回调handleBeginFrame()、handleDrawFrame()
handleBeginFrame: Called by the engine to prepare the framework to produce a new frame.
handleDrawFrame: Called by the engine to produce a new frame.
通过计算handleBeginFrame和handleDrawFrame之间的时间间隔计算帧率主要流程如下图 效果
到这里我们完成Flutter中页面帧率的统计这种方式统计的是UI TaskRunner中的CPU操作耗时GPU操作在Flutter引擎内部实现要修改引擎来监控完整的渲染耗时我们目前大部分的场景没有复杂到gpu卡顿问题主要还是集中在CPU所以说可以反应出大部分问题。从线上数据来看release模式下Flutter的流畅度还是蛮不错的ios的主要页面均值基本维持在50fps以上android相对ios略低。这里需要注意的是帧率的均值fps在反复滑动过程中会有一个稀释效果导致一些卡顿问题没有暴露出来所以除了fps均值需要综合掉帧范围、卡顿秒数、滑动时长等数据才能反应出页面流畅度情况。
页面加载时长
集团内部高可用方案统计Native页面加载时长是通过容器初始化后开启定时器在容器layout的时候检查屏幕渲染程度计算可见组件的屏幕覆盖率满足条件水平60%垂直80%以上认为满足页面填充程度再检查主线程心跳判断是否加载完成 再来看看weex页面加载流程和统计数据的定义 Weex的页面刷新稳定定义屏幕内view渲染完成且view树稳定的时间
具体实现当屏幕内发生view的add/rm操作时认为是可交互点,记录数据。直到没有再发生为止。 在概念上Flutter和weex的首屏时长和可交互时长并不完全一致Flutter之所以选择从路由跳转开始计算时长主要是因为这种计算方式更贴近用户体验可以获取更多的问题信息比如路由跳转的时长问题等。
Flutter的可交互时长end点采用的算法与native一致可见组件满足页面填充程度并且完成心跳检查的情况下任务可交互另外对于一些比较空的页面组件面积小无法达到水平60%垂直80%的条件就用交互前最后一次Frame刷新时间点作为end点。
具体流程如下图 效果
由于debug模式采用的JIT编译debug模式下体验加载时长偏长但是release模式下的AOT编译时长明显缩短很多整体页面加载时长还是要优于weex。
Exception率
Flutter部分exception/error 会导致代码后面的逻辑没有走到造成页面或逻辑bug所以flutter的exception需要作为稳定性的标准之一
定义
FlutterException率 exception发生次数 / flutter页面PV
分子exception发生次数已过滤掉白名单
Flutter内部assert、try-catch和一些异常逻辑的地方会统一调用FlutterError.onError
通过重定向FlutterError.onError到自己的方法中监测exception发生次数并上报exception信息
分母flutter页面PV
具体实现如下
FutureNull main() async {FlutterError.onError (FlutterErrorDetails details) async {Zone.current.handleUncaughtError(details.exception, details.stack);};runZonedFutureNull(() async {runApp(new HomeApp());}, onError: (error, stackTrace) async {await _reportError(error, stackTrace);});
}
其中FlutterError.onError只会捕获Flutter framework层的error和exception官方建议将这个方法按照自己的exception捕获上报需求定制。在实践过程中我们遇到很多不会对用户体验产生任何影响的exception会被频繁触发这类没有改善意义的exception可以添加白名单过滤上报。
效果
有了线上exception的监控可以及早发现隐患获取问题堆栈信息方便定位bug提示整体稳定性
总结
到这里我们完成Flutter页面滑动流畅度、页面加载时长和Exception率的统计对于Flutter的性能有一个具体的数字化标准对以后的用户体验提升和性能问题排查提供基础。目前闲鱼客户端的商品详情页和主发布页已经全量Flutter化感兴趣的同学可以体验下这两个页面和其他页面的性能差异最后欢迎大家提供反馈和建议。
原文链接 本文为云栖社区原创内容未经允许不得转载。