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

背景

闲鱼客户端的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: 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

具体实现如下:

Future<Null> main() async {FlutterError.onError = (FlutterErrorDetails details) async {Zone.current.handleUncaughtError(details.exception, details.stack);};runZoned<Future<Null>>(() 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化,感兴趣的同学可以体验下这两个页面和其他页面的性能差异,最后欢迎大家提供反馈和建议。


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/519121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里3篇技术论文入选国际顶级会议FAST2020,全球第一!

2月26日&#xff0c;存储行业顶级国际会议FAST2020&#xff08;18th USENIX Conference on File and Storage Technologies&#xff09;在美国圣克拉拉举行&#xff0c;大会公开论文名单显示&#xff0c;阿里巴巴3篇第一作者论文入选&#xff0c;是全球入选数最多的企业。 FAS…

oracle11g linux 日期格式设置

下面的过程把oracle 的日期格式设置成 yyyy-mm-dd hh24:mi:ss(1) 使用 oracle 用户登录(2) 在.bash_profile里增加以下两条环境变量export NLS_LANGamerican_america.ZHS16GBK export NLS_DATE_FORMAT"YYYY-MM-DD HH24:MI:SS" (3) 执行一下"source .bash_profil…

一份还热乎的蚂蚁金服面经(已拿Offer)!附答案!!

本文来自我的知识星球的球友投稿&#xff0c;他在最近的校招中拿到了蚂蚁金服的实习生Offer&#xff0c;整体思路和面试题目由作者——泽林提供&#xff0c;部分答案由Hollis整理自知识星球《Hollis和他的朋友们》中「直面Java」板块。 经历了漫长一个月的等待&#xff0c;终于…

linux RssFile什么含义,什么是RSS

导读RSS 指 Really Simple Syndication(真正简易联合),RSS 的 元素可描述 RSS feed。RSS 元素RSS 的 元素可描述 RSS feed。请看下面这个 RSS 文档&#xff1a;<?xml version"1.0"encoding"UTF-8"?>菜鸟教程首页http://www.runoob.com免费编程教程…

linux CPU、内存、I/O、磁盘等监控统一解决方案

文章目录一、效果图二、软件安装配置2.1. nmon安装2.2. 权限赋予2.3. 脚本制作2.4. 脚本运行三、解析监控文件3.1. 监控文件下载3.2. 解析监控文件3.3. 监控指标总览补充内存计算方式需求背景: 性能测试过程中监控服务器健康(CPU、内存、I/O、磁盘)指标的状态 一、效果图 二、软…

数据科学家常见的5个SQL面试问题

作者 | Alexei Ledenev翻译 | 天道酬勤&#xff0c;责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;在任何以数据为中心的工作中&#xff0c;对SQL有深刻的理解都是成功的关键&#xff0c;尽管这不是工作中最有趣的部分。事实上&#xff0c;除了…

c语言程序滞留,c语言有个可以使程序延时的语句是什么?

满意答案hsgfzdg99推荐于 2017.09.11采纳率&#xff1a;57% 等级&#xff1a;9已帮助&#xff1a;1169人Sleep函数:功 能: 执行挂起一段时间  用 法: unsigned sleep(unsigned seconds);  注意:  在VC中使用带上头文件#include  在VC中,Sleep中的第一个英文字符为大写的…

从濒临解散到浴火重生,OceanBase 这十年经历了什么?

阿里妹导读&#xff1a;谈及国产自研数据库&#xff0c;就不得不提 OceanBase。与很多人想象不同的是&#xff0c;OceanBase 并非衔着金钥匙出生的宠儿。相反&#xff0c;它曾无人看好、困难重重&#xff0c;整个团队甚至数度濒临解散。 从危在旦夕到浴火重生&#xff0c;Ocean…

两成开发者月薪超 1.7 万、算法工程师最紧缺! | 中国开发者年度报告

整理 | 郭芮 责编 | 唐小引 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; “求知若饥&#xff0c;虚心若愚”——这个原本出自《全球概览》的俳句&#xff0c;因为乔布斯在斯坦福大学毕业演讲中的引用而备受推崇&#xff0c;流传成为 IT 界的至理名言之一。在…

拒绝版权流氓!阿里巴巴重磅发布免费商用字体

UCAN 2019 设计大会在杭州国际博览中心开幕&#xff0c;超过 4000 位来自世界各地的设计师参与了这场阿里巴巴设计举办的盛会。 继去年品牌升级为阿里巴巴设计&#xff08;Alibaba Design&#xff09;后&#xff0c;阿里巴巴经济体设计委员会委员长杨光&#xff08;青云&#…

全站CSRF漏洞

文章目录二、解决方案2.1. 创建CSRF防御统一管理2.2. 创建csrfToken校验2.3. 加密工具类2.4. 查询实战2.5. 添加和更新实战默认guns不支持添加headers的需要添加ax2二、解决方案 2.1. 创建CSRF防御统一管理 package com.gblfy.sys.config.web.csrf;import com.gblfy.base.uti…

AutoML数据增广

DeepAugment是一个专注于数据扩充的自动化工具。 它利用贝叶斯优化来发现针对您的图像数据集定制的数据增强策略。 DeepAugment的主要优点和特点是&#xff1a; 降低CNN模型的错误率(WRN-28-10显示CIFAR10的错误率降低了60%)通过自动化流程可以节省时间比谷歌之前的解决方案—…

基于TensorFlow.js的JavaScript机器学习

Credits: aijs.rocks 虽然python或r编程语言有一个相对容易的学习曲线&#xff0c;但是Web开发人员更喜欢在他们舒适的javascript区域内做事情。目前来看&#xff0c;node.js已经开始向每个领域应用javascript&#xff0c;在这一大趋势下我们需要理解并使用JS进行机器学习。由…

阿里巴巴、支付宝员工都在用的知识管理工具,究竟有何特别?

公司内各部门工作文档难以共享&#xff1f;缺乏高效便捷的团队协作工具&#xff1f;文档放到在线云平台担心安全&#xff1f;…… 2019年4月22日&#xff0c;蚂蚁金服旗下知识创作与分享工具语雀发布“空间功能”。语雀在支持在线文档编写、多人协作、灵活的团队管理和金融级安…

探索处理数据的新方法,8 个重点带你搞懂云数据库——DBaaS(数据库即服务)到底是什么!...

作者| Rohan Wadiwala、Mangesh More翻译 | 天道酬勤&#xff0c;编辑 | Carol出品| CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;在分析的世界中&#xff0c;网站的每次点击都是数据分析的候选对象&#xff0c;显然&#xff0c;这会涉及大量的数据生成。对于海…

阿里开发者招聘节 | 面试题05: 关于epoll和select的区别,哪些说法是正确的?

为帮助开发者们提升面试技能、有机会入职阿里&#xff0c;云栖社区特别制作了这个专辑——阿里巴巴资深技术专家们结合多年的工作、面试经验总结提炼而成的面试真题这一次将陆续放出&#xff08;面试题官方参考答案将在专辑结束后统一汇总分享&#xff0c;点此进入答题并围观他…

c语言printf里的自增,笔试题记录:C语言——函数printf()的执行机制;先自增与后自增的区别;取值运算与自增运算的优先级...

考点&#xff1a;函数printf()的执行机制&#xff1a;参数按照从右至左的顺序入栈&#xff0c;在调用时出栈&#xff1b;考察运算符“”在变量之前、变量之后的运算机制&#xff0c;即是先赋值/还是先自增*(p)、*(p)、*(p1)之间的区别后面两项主要是考察&#xff1a;取值运算与…

分布式系统:CAP 理论的前世今生

CAP 理论是分布式系统设计中的一个重要理论&#xff0c;虽然它为系统设计提供了非常有用的依据&#xff0c;但是也带来了很多误解。本文将从 CAP 诞生的背景说起&#xff0c;然后对理论进行解释&#xff0c;最后对 CAP 在当前背景下的一些新理解进行分析&#xff0c;澄清一些对…

你的企业混合云了吗?来看看评估混合云解决方案时要注意的6个原则!

作者| Matt Kimball翻译 | 天道酬勤&#xff0c;编辑 | Carol出品| CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;混合云如今很流行。几乎每个IT公司都声称已部署了解决方案&#xff0c;但实际上实现的却很少。相反&#xff0c;它们拥有与多个云实例进行某种程度…

c语言int超出范围字符串,Go返回int64类型字段超出javascript Number范围的解决方法...

Go返回int64类型字段超出javascript Number范围的解决方法最近在项目中&#xff0c;一个go服务给前端提供了一个接口&#xff0c;返回json格式数据&#xff0c;其中Int64字段会超出javascript Number可表示的最大的Int值会丢精度&#xff0c;可以通过返回string类型值来屏蔽这个…