背景

闲鱼客户端的flutter页面已经服务上亿级用户,这个时候Flutter页面的用户体验尤其重要,完善Flutter性能稳定性监控体系,可以及早发现线上性能问题,也可以作为用户体验提升的衡量标准。那么Flutter的性能到底如何?是否像官方宣传的那么丝滑?Native的性能指标是否可以用来检测Flutter页面?下面给大家分享我们在实践中总结出来的Flutter的性能稳定性监控方案。

目标

过度的丢帧从视觉上会出现卡顿现象,体现在用户滑动操作不流畅;页面加载耗时过长容易中断操作流程;Flutter部分exception会导致发生异常代码后面的逻辑没有走到从而造成逻辑bug甚至白屏。这些问题很容易考验用户耐心,引起用户反感。

所以我们制定以下三个指标作为线上Flutter性能稳定性标准:

  1. 页面滑动流畅度
  2. 页面加载耗时(首屏时长+可交互时长)
  3. Exception率

最终目标是让这些数据指标驱动Flutter用户体验升级。

页面滑动流畅度

我们先大概了解下屏幕渲染流程:CPU先把UI对象转变GPU可以识别的信息存储进displaylist列表,GPU执行绘图指令来执行displaylist,取出相应的图元信息,进行栅格化渲染,显示到屏幕上,这样一个循环的过程实现屏幕刷新。

闲鱼客户端采用的Native、Flutter混合技术方案,Native页面FPS监控采用集团高可用方案,Flutter页面是否可以直接采用这套方案监控?

普遍的FPS检测方案Android端采用的是Choreographer.FrameCallBack,IOS采用的是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和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.

通过重定向FlutterError.到自己的方法中监测exception发生次数,并上报exception信息

分母:flutter页面PV

具体实现如下:

其中,FlutterError.只会捕获Flutter framework层的error和exception,官方建议将这个方法按照自己的exception捕获上报需求定制。在实践过程中,我们遇到很多不会对用户体验产生任何影响的exception会被频繁触发,这类没有改善意义的exception可以添加白名单过滤上报。

效果

有了线上exception的监控,可以及早发现隐患,获取问题堆栈信息,方便定位bug,提示整体稳定性

总结

到这里,我们完成Flutter页面滑动流畅度、页面加载时长和Exception率的统计,对于Flutter的性能有一个具体的数字化标准,对以后的用户体验提升和性能问题排查提供基础。目前闲鱼客户端的商品详情页和主发布页已经全量Flutter化,感兴趣的同学可以体验下这两个页面和其他页面的性能差异,最后欢迎大家提供反馈和建议。

-----------------------------------------

本文作者:闲鱼技术-三莅

走近科学,探究阿里闲鱼团队通过数据提升Flutter体验的真相相关推荐

  1. 看!闲鱼又开源了一个 Flutter 开发利器

    阿里妹导读:随着 Flutter 这一框架的快速发展,有越来越多的业务开始使用 Flutter 来重构或新建其产品.但在我们的实践过程中发现,一方面 Flutter 开发效率高,性能优异,跨平台表现好 ...

  2. 如何用解耦合提升开发效率?闲鱼团队有了新发现

    阿里妹导读:在业务开发的过程中,往往存在平台代码和业务代码耦合严重难以分离.业务和业务之间代码交织缺少拆解的现象.平台和业务代码交织导致不易修改,不同业务的代码交织增加了不同负责团队之间的协同成本.因 ...

  3. 阿里闲鱼App服务端在ServiceMesh的探索和实践

    文章来源:咸鱼技术(XYtech_Alibaba) 作者:柬超 背景 在阿里服务端开发以Java为主的大背景下,其他异构语言业务如何调用现有Java服务,如何与集团中间件打通,就成为使用非Java语言 ...

  4. Flutter高内聚组件怎么做?阿里闲鱼打造开源高效方案!

    fish_redux是闲鱼技术团队打造的flutter应用开发框架,旨在解决页面内组件间的高内聚.低耦合问题.开源地址:https://github.com/alibaba/fish-redux 从r ...

  5. 互联网首发 | 闲鱼程序员公开多年 Flutter 实践经验

    简介 flutter-boot核心解决了混合开发模式下的两个问题:flutter混合开发的工程化设计和混合栈.那flutter-boot是如何解决的呢? 首先在工程化设计的问题上,flutter-bo ...

  6. 使用DGL实现基于闲鱼图进行边分类算法

    闲鱼图算法解析和使用DGL进行实现 2019年阿里闲鱼团队在CIKM 2019上发了一篇进行Spam评论的检测算法,用到了GNN的思想.论文显示结果比较好.但是由于首先它们并没有开放数据,且也没开源算 ...

  7. 闲鱼提效最佳实践:打造OKR机制下的数据驱动敏捷团队

    讲师介绍 淘系技术部 | 闲鱼技术部 | 鬼才 "闲鱼从零发展到过亿MAU的APP不同阶段的业务特点.核心问题以及针对性的优化,来阐述PMO视角项目管理.敏捷协同的演进思路与心得." ...

  8. 【干货】阿里资深无线技术专家孙兵谈闲鱼社区技术架构演进

    近期在ArchSummit北京会议上,阿里巴巴资深无线技术专家孙兵(花名酒丐)发表了<网格社区-闲鱼技术架构演讲>主题演讲.孙兵2011年加入阿里巴巴,先后在B2B.淘宝.手机淘宝等部门负 ...

  9. 阿里技术分享:闲鱼IM基于Flutter的移动端跨端改造实践

    本文由阿里闲鱼技术团队祈晴分享,本次有修订和改动,感谢作者的技术分享. 1.内容概述 本文总结了阿里闲鱼技术团队使用Flutter在对闲鱼IM进行移动端跨端改造过程中的技术实践等,文中对比了传统Nat ...

最新文章

  1. 19.7 主动模式和被动模式 添加监控主机 添加自定义模板 处理图形
  2. 会计电算化之Excel
  3. java if else 过多_Java中if-else过多怎么解决
  4. C++ 类的抽象初练
  5. 2017 前端大事件和趋势回顾,2018 何去何从?
  6. 知道吗?9个搜索引擎优化(SEO)最佳实践
  7. 长虹电视+刷回android,【原创教程】长虹智能电视Q3T手动升级and刷机救砖教程
  8. 用html制作带阴影小球弹跳,AE怎么制作一个有影子的弹跳小球动画?
  9. 【基于stm32f103c8t6RFID-RC522智能开关】
  10. 计算机信息检索技术实质上是逻辑运算,在信息检索的实际过程中,如需要扩大检索范围时,如何调整检索策略...
  11. Xmind 8 Pro破解版安装激活教程(Windows版)
  12. PHP-SDK实现微信付款码支付
  13. CTGU 2021春-MySQL数据库实验2:基本查询5-6关,共5小题全代码+信息表+通关截图!
  14. 树莓派4B:智能植物管家
  15. 【火炉炼AI】机器学习023-使用层次聚类算法构建模型
  16. MVC5 + EF6 + Bootstrap3 (9) HtmlHelper用法大全(下)
  17. C语言输出浮点数的符号、整数部分和小数部分
  18. 【计算机毕业设计】jsp+ssm驾校预约管理系统
  19. 互联网产品经理必备的工具
  20. Mysql数据库之结构同步

热门文章

  1. mysql查询父子关系树_swt 生成树[读取Mysql数据库中的父子关系表]
  2. python定义匿名函数关键字_python语言的匿名函数、7种可调用对象以及用户定义的可调用类型...
  3. 内存模型 C++ 和Java内存模型
  4. Spring Boot——RabbitMQ
  5. springMVC注解中@RequestMapping中常用参数value params 以及@RequestParam 详解
  6. 【双100%提交】剑指 Offer 09. 用两个栈实现队列
  7. 简便解法:1004 成绩排名 (20分)
  8. Python 测试开发教程
  9. Web前端开发笔记——第二章 HTML语言 第七节 表格标签
  10. RAID简介与示例演示