Flutter卡顿优化锦辑

原文连接html

Flutter卡顿优化必备基础知识

首先,在作性能调优以前,咱们应该对flutter相关基础知识有必定的了解,否则咱们无从作起,首先,咱们要了解flutter是干吗的--Flutter 是谷歌2018年发布的跨平台移动UI框架android

而后,他相对于其余跨平台开发框架来讲,是高效的,至于他为何高效,缘由是由于:算法

他是直接调用Skia框架,而其余框架须要借助现有的原始框架来转一下,在才开始去调用Skia框架,这一来二去,确定就有所消耗,这是其一,而后,咱们还须要知道flutter的四个线程。api

四个线程

分别是:性能优化

平台线程

该平台的主线程。插件代码在这里运行。更多信息请参阅:iOS 的程序 (UIKit) 文档,或者 Android 的主线程 (MainThread) 文档。性能图层并不会展现该线程。bash

DartUI 线程

UI 线程在 Dart VM 执行 Dart 代码。该线程包括开发者写下的代码和 Flutter 框架根据应用行为生成的代码。当应用建立和展现场景的时候,UI 线程首先创建一个 图层树(layer tree) ,一个包含设备无关的渲染命令的轻量对象,并将图层树发送到 GPU 线程来渲染到设备上。不要阻塞这个线程!在性能图层的最低栏展现该线程。app

GPU 线程

GPU 线程取回图层树并通知 GPU 渲染。尽管没法直接与 GPU 线程或其数据通讯,但若是该线程变慢,必定是开发者 Dart 代码中的某处致使的。图形库 Skia 在该线程运行,有时也被叫作光栅器 (rasterizer) 线程。在性能图层的最顶栏显示该线程。框架

I/O 线程

可能阻塞 UI 或者 GPU 线程的耗时任务(大多数状况下是 I/O)。该线程并不会在性能图层中展现。函数

因此,咱们作性能优化,关心DartUI,关心GPU两个线程,掉不掉帧,卡不卡的关键,就看这两位了,并且在99%状况下,做为Flutter开发人员,咱们咱们基本上解决好,DartUI线程上的问题,就==解决了渲染性能问题。工具

三棵树

  • Widget是为Element描述须要的配置, 负责建立Element,决定Element是否须要更新。Flutter Framework经过差分算法比对Widget树先后的变化,决定Element的State是否改变。当重建Widget树后并未发生改变, 则Element不会触发重绘,则就是Widget树的重建并不必定会触发Element树的重建。
  • Element表示Widget配置树的特定位置的一个实例,同时持有Widget和RenderObject,负责管理Widget配置和RenderObject渲染。Element状态由Flutter Framework管理, 开发人员只需更改Widget便可。
  • RenderObject表示渲染树的一个对象,负责真正的渲染工做,好比测量大小、位置、绘制等都由RenderObject完成。

为了更加直观的表示3个树的从生到死,我不得不抛出下面这幅图来

而后,咱们常常在作性能调优的时候,会用到timeline工具,你会看到这样一幅图:

如今串起来了吗,4个线程build---layout---paint三个阶段是否是都一目了然,各发生在什么地方,什么阶段,谁先谁后。

因此,咱们说 要解决卡顿掉帧的问题,就是要解决build,layout,paint这三个阶段各函数执行耗时的问题。

具体如何作性能优化

首先,咱们配置下环境,这里我配置这个变量debugProfileBuildsEnabled=true否则,我不知道build他具体作了些啥,观望台默认不会告诉我。通常来讲,放在main函数中,在runApp以前开启便可,好比我是这么干的:

这里面有一些其余须要用到的开关,能够在数据不足的时候开启,这样咱们参考的数据多些,优化的参考点就明确些。

而后,咱们执行 flutter run --profile ,请记住,咱们须要在profile模式来性能调优,debug模式由于在渲染过程当中记录了不少分析数据且加上支持热重载的特性是损失了不少性能为代价的,profile模式更加接近release模式性能。

而后跑起来了,会出现一个连接:

点一下就去了观望台了,固然,你也可使用devTools,貌似后面会取代观望台。devTools的启动姿式是:

flutter pub global activate devtools
devTools复制代码

先安装,而后在直接运行便可:

点击这个连接,会弹出一个网页来,让你输入url,这个url就是咱们那个观望台的url,所以你彷佛秒懂了,然来,devTools是在观望台的基础至上作的一个分析工具,因此,Google必定是以为观望台不大友好了,然而,遗憾的是,devTools并非特别全面,由于如今仍是preview阶段嘛,一切都会好起来的。

好的,假如,咱们的app有性能问题,咱们就会打开观望台,而后打开timeLine,点击Flutter Develop,而后在你以为有问题的页面多操做记下,而后点击右上角Refresh按钮,就会出现:

一般来讲,很容易发现有问题的地方,明显那个会比较宽比较长的地方就比较能够,这种一遍就能够定位页面加载比较慢了,而后咱们点击向下箭头,把他放大点看看

大概就看到了,偶,而后,咱们点击选择,在选择一个范围看看统计效果:

这时候,咱们就发现问题了,而后这个也加载了这么多个TipCacheNetWorkImage,而后每一个大概要2ms,而后我这个是一个列表页:

因此,一共就有8个这样的控件要渲染,而他,就占用8 *2.188 > 16ms,所以咱们找到了优化点,解决这个就能够加速渲染了,这里只是举例找到存在性能瓶颈的地方,具体相关函数耗时的优化,相信你们都懂的,这就是算法相关的问题了。

而后就是几点代码建议

一、尽可能将setState放在叶子节点,好处是build时影响范围极小,简称局部刷新

二、能不用 Opacity Widget,就尽可能不要用,由于这货会粗发GPU一个saveLayer的指令,作Skia的大神说,这个指令至关耗时。

三、使用ListView.builder()而不是直接使用ListView()来构建列表。

四、对于频繁更新的控件(好比倒计时,秒表),使用RepaintBoundary隔离它,让他在一个独立的paint区域。

五、使用const来修饰永远不须要变动的控件。

六、优先使用StateLessWidget,而不是所有用StateFulWidget

七、使用Visibility控件替换if/else,有些小伙伴喜欢else时return一个 占位控件,须不知,这种效率是没有Visibility高效的。

参考资料

调试 Flutter 应用 - Flutter 中文文档 - Flutter 社区中文资源

zhuanlan.zhihu.com/p/88478737

files.flutter-io.cn/events/gdd2…

Flutter 应用性能优化最佳实践 - Flutter 中文文档 - Flutter 社区中文资源

mrale.ph/dartvm/

medium.com/flutter/man…

相关文章
相关标签/搜索