作者 / Yuqian Li & Shams Zakhour
高性能是 Flutter 的关键特性之一。我们希望通过本文着重分享在 2019 年下半年由整个 Flutter 社群实现的性能优化。(虽然 2020 年已经过去大半,但我们认为感谢开发者们做出的贡献虽晚不迟!)
当然,如果您在 2020 年帮助 Flutter 提升性能,您也将出现在未来的英雄榜中。我们希望通过分享这些成就,可以激励更多的开发者贡献能量!
我们尤其鼓励编写性能测试来量化性能上的提升,并防止该性能在未来出现倒退。因此,我们在含有量化结果的性能优化的详细说明中,会特别列出每个做出贡献的开发者。
以下是 2019 年下半年的 Flutter 性能汇总和量化结果分享,您可以在后文中阅读性能提升详细内容和贡献来源。
2019 年第 4 季度 (10 月 - 12 月)
已量化的改进
快速滚动浏览大型图像时,内存占用减少 70%
简单 iOS 动画的 CPU/GPU 占用降低 40%
41% 的光标性能加速
通过修复光栅缓存节流,将列表滚动速度提高 10%
缓存性能数据使得仪表板加载速度提高 37 倍
构建 APK 的速度提高至 2.3 倍
Flutter 引擎提交时记录的性能指标增加 103 个
应用大小缩减 20%
Dart FFI 性能提升了 108 倍
紧凑代码的性能提升 10% – 15%
通过新的增量序列化器将 flutter 测试速度提高了 2.2 倍
通过向 Dart VM JIT 提供内联提示将内核二进制序列化速度提高 10%
异步繁重代码的性能提升了 30%
其他改进
修复了在 iOS 上使用 PlatformView 时的内存泄漏问题
修复了在 iOS 上播放动画时的内存泄漏问题
修复了许多其它的 iOS 内存泄漏
已开始改造 flutter.dev 上的性能 (Performance) 页面并添加了有关衡量应用大小的操作说明
更正了第一帧等待逻辑和衡量
DevTools 添加了完整时间线模式,并支持异步和记录的追踪
IntelliJ 插件修复了 120FPS 支持
许多时间线追踪改进
2019 年第 3 季度 (7 月 - 9 月)
已量化的改进
矩形和点变换速度提升了 1.5–5 倍
iPhone X/Xs 滚动时丢失的帧数减少 N/2–1
通过并行初始化将引擎启动和关闭时间缩短 15%
着色器预热的启动速度加快 14.57 毫秒,内存使用量减少 8MB
代码大小缩减了 1.02%-8.04%
Flutter 在 Fuchsia 上的 FPS 提高多达 2 倍;改进了帧时间安排
已量化的回退修复
iOS 上 BackdropFilter 的速度提高 3 倍
其他改进
DevTools 支持各种显示刷新速率 (例如 60 FPS、120 FPS 等)
目前 VSCode 插件对项目的扫描是异步扫描,这应该会提升扩展程序激活速度并降低触发 VS Code "扩展导致高 CPU" 警告的几率
iPhone Xs 已被添加至 Flutter 设备实验室进行基准测试
详细说明
2019 年第 4 季度已量化的改进
快速滚动浏览大型图像时,内存占用减少 70%
PR 14265: 清理 IO 线程 GrContext
https://github.com/flutter/engine/pull/14265
PR 46184: 针对快速滚动大型图像的内存测试
https://github.com/flutter/flutter/pull/46184
仪表板: fast_scroll_large_images__memory 中位数差值减少了 70% (从 400MB 减少到 120MB)
https://flutter-dashboard.appspot.com/benchmarks.html
Issue 19558: 需要清理 IO 线程 GrContext 内存
https://github.com/flutter/flutter/issues/19558
贡献者: liyuqian、dnfield、chinmaygarde
https://github.com/liyuqian
https://github.com/dnfield
https://github.com/chinmaygarde
简单 iOS 动画的 CPU/GPU 占用降低 40%
PR 14104: 重新设计更简单的条件离屏渲染以实现屏幕读取支持
https://github.com/flutter/engine/pull/14104
PR 13976: 根据需求动态确定是否使用离屏表面
https://github.com/flutter/engine/pull/13976
PR 31865: iPhone 6 上的简单动画大量消耗 (约 20%) CPU/GPU/电量
https://github.com/flutter/flutter/issues/31865
simple_animation_perf_iphonexs 的 cpu_percentage 和 gpu_percentage 减少了 40% (从 23%-CPU-14%-GPU 减少到 13%-CPU-8.5%-GPU)
https://github.com/flutter/flutter/issues/31865#issuecomment-566268237
贡献者: flar、liyuqian、hixie、chinmaygarde
https://github.com/flar
http://github.com/liyuqian
https://github.com/hixie
http://github.com/chinmaygarde
41% 的光标性能加速
PR 46720: 传递 _caretPrototype 以防止缓存丢失
https://github.com/flutter/flutter/pull/46720
PR 46720: 第 90 百分位帧的构建时间缩短了 41% (从 6.709 毫秒缩短到 4.756 毫秒)
https://github.com/flutter/flutter/pull/46720
[已修复] Issue 24522: 光标性能低下,每帧的 GPU 时间过长
https://github.com/flutter/flutter/issues/24522
贡献者: garyqian、liyuqian、justinmc
https://github.com/garyqian
http://github.com/liyuqian
https://github.com/justinmc
通过修复光栅缓存节流,将列表滚动速度提高 10%
PR 31865: iPhone 6 上的简单动画大量消耗 (约 20%) CPU/GPU/电量
https://github.com/flutter/flutter/issues/31865
PR 13710: 修复图片光栅缓存节流
https://github.com/flutter/engine/pull/13710
PR 45050: 为照片光栅缓存添加 perf 测试
https://github.com/flutter/flutter/pull/45050
利用 PR 13710 (修复图片光栅缓存节流) 修复了关键问题 43083: 列表滚动不畅
https://github.com/flutter/flutter/pull/45050
贡献者: liyuqian、chinmaygarde、flar、cyanglaz、zsunkun
http://github.com/liyuqian
http://github.com/chinmaygarde
https://github.com/flar
https://github.com/cyanglaz
https://github.com/zsunkun
缓存基准加载速度提高至 37 倍 (仪表板)
PR 494: 缓存 get-benchmark
https://github.com/flutter/cocoon/pull/494
PR 484: /api/public/get-status 提供缓存响应
https://github.com/flutter/cocoon/pull/484
基准加载速度提高至 37 倍 (从 37 秒缩短至 1 秒)
https://github.com/flutter/cocoon/pull/494#issue-333227543
贡献者: caseyhillers、tvolkert、digiter、jonahwilliams
https://github.com/caseyhillers
https://github.com/tvolkert
https://github.com/digiter
https://github.com/jonahwilliams
构建 APK 的速度提高至 2.3 倍
PR 44534: 通过并发运行 gen_snapshot 提高构建 APK 的性能 (大约 50%)
https://github.com/flutter/flutter/pull/44534
针对目标平台 android-arm、android-arm64 和 android-x64,将 APK 的发布版本构建速度提高至 2.3 倍 (从 140 秒缩短至 60 秒)
https://github.com/flutter/flutter/pull/44534#issue-339112036
贡献者: jonahwilliams、blasten、zanderso、xster
https://github.com/jonahwilliams
https://github.com/blasten
https://github.com/zanderso
https://github.com/xster
Flutter 引擎提交时记录的性能指标增加 103 个
PR 14556: 运行和收集指标
https://github.com/flutter/engine/pull/14556
相关 issue: PR 37434: 集中性能指标、提供通用提醒,并改进性能仪表板
https://github.com/flutter/flutter/issues/37434
贡献者: liyuqian、digiter、keyonghan、godofredoc、cbracken
http://github.com/liyuqian
https://github.com/digiter
https://github.com/keyonghan
https://github.com/godofredoc
https://github.com/cbracken
应用大小缩减 20%
3% 来自将 PC 偏移 (offset) 从 StackMaps 中移出
https://github.com/dart-lang/sdk/commit/a2bb7301c5795e6b28089a8dc96e6ab5ca798e22
2.58% 来自进一步压缩之前在 StackMaps 中的信息
https://github.com/dart-lang/sdk/commit/d77f4913a18ecce8c4be95cbaa4299ff1521dc10
1% 来自尽可能规范化 CompressedStackMaps 负载 (如可能)
https://github.com/dart-lang/sdk/commit/dc808f3fcbf7e6de7e2b25441ff7ed891362e70a
2% 来自在裸机模式下完全启用指令去重
https://github.com/dart-lang/sdk/commit/e2faac751e1ef3707730e6e48f4d8f22ecbf35c3
0.3% 来自不为需要参数描述符的函数生成单态序言
https://github.com/dart-lang/sdk/commit/f6477854cdb0da052be3423a24961feaf5a0d845
1% 来自舍弃冗余的 null 初始化存储
https://github.com/dart-lang/sdk/commit/46cef9bfddf3cfc05618448d228f0e3377058baf
6% 来自减少指令对齐并移除一些调试陷阱指令
https://github.com/dart-lang/sdk/commit/8e7ffafbafc8203361111ddcafe0e0fcc372edf8
1.2% 来自在调用存根期间而非每个函数序言中调整 CSP
https://github.com/dart-lang/sdk/commit/c873220e43af1a1f4675df4108e575465e598578
1% 来自 ARM64: 屏蔽 R22 以保留 NullObject()
https://github.com/dart-lang/sdk/commit/f8d42542ddd40c06bb71d6fb85d78ed4bbffa785
2.5% 来自全程序常量传播
https://github.com/dart-lang/sdk/commit/f56b0f690789b6f0e2e5bc1340abf4eba414b7a0
0.77% 来自消除死代码
https://github.com/dart-lang/sdk/commit/b69596bb1ba81874e4b9d7a577071c67c357ec39
贡献者: mraleph、alexmarkov、rmacnak-google、mkustermann、sstrickl、aartbik
https://github.com/mraleph
https://github.com/alexmarkov
https://github.com/rmacnak-google
https://github.com/mkustermann
https://github.com/sstrickl
https://github.com/aartbik
Dart FFI 性能提升了 108 倍
Gerrit 120661: 优化静态已知类型的指针操作
https://dart-review.googlesource.com/c/sdk/+/120661
Gerrit 119645: 索引读取和存储的指针优化
https://dart-review.googlesource.com/c/sdk/+/119645
Gerrit 121580: 允许在 AoT 中内嵌强制优化的函数
https://dart-review.googlesource.com/c/sdk/+/121580
贡献者: dcharkes、mkustermann、sjindel、alexmarkov
https://github.com/dcharkes
https://github.com/mkustermann
https://github.com/sjindel
https://github.com/alexmarkov
紧凑代码的性能提升 10–15%
Gerrit 117200: 循环分析和 BCE 改进
https://dart-review.googlesource.com/c/sdk/+/117200
golem armv7 的性能提高了 10–15%,以及 TypedData Bench: Gerrit 117200: 循环分析和 BCE 改进
https://dart-review.googlesource.com/c/sdk/+/117200
贡献者: aartbik、mkustermann、mraleph
https://github.com/aartbik
https://github.com/mkustermann
https://github.com/mraleph
通过新的增量序列化器将 flutter 测试速度提高了 2.2 倍
Gerrit 121121: 默认启用增量序列化器
https://dart-review.googlesource.com/c/sdk/+/121121
"flutter test" 速度提高了 2.2 倍 (时间从 3:38 缩短至 1:39)
贡献者: jensjoha、alexmarkov
https://github.com/jensjoha
https://github.com/alexmarkov
通过向 Dart VM JIT 提供内联提示将内核二进制序列化速度提高 10%
Gerrit 119540: 向内核序列化中的某些方法添加 VM 友好内联指令
https://dart-review.googlesource.com/c/sdk/+/119540
贡献者: jensjoha、johnniwinther
https://github.com/jensjoha
https://github.com/johnniwinther
异步繁重代码的性能提升了 30%
添加非紧急异步堆栈帧收集器
https://dart-review.googlesource.com/c/sdk/+/122644
贡献者: cskau-g、mkustermann、mraleph
https://github.com/cskau-g
https://github.com/mkustermann
https://github.com/mraleph
2019 年第 4 季度其他改进
修复了在 iOS 上使用 PlatformView 时的内存泄漏问题
修复使用 PlatformView [IOS] 时的内存泄漏
https://github.com/flutter/engine/pull/7919
使用 PlatformView [IOS] 时的内存泄漏
https://github.com/flutter/flutter/issues/24714
修复了在 iOS 上播放动画时的内存泄漏问题
Gerrit 260538: 不为创建无法缓存纹理的生成器分配无效消息
https://skia-review.googlesource.com/c/skia/+/260538
在 iOS 上播放动画时的内存泄漏
https://github.com/flutter/flutter/issues/47108
修复了更多 iOS 内存泄漏
https://github.com/flutter/engine/pull/14275
https://github.com/flutter/engine/pull/14326
https://github.com/flutter/flutter/issues/35243
已开始改造 flutter.dev 上的性能 (Performance) 页面并添加了有关衡量应用大小的操作说明
PR 3159: 性能
https://github.com/flutter/website/pull/3159/
更正了第一帧等待逻辑和衡量
PR 37192: 重新 "修复追踪和驱动程序中的第一帧逻辑 (#35297)"
https://github.com/flutter/flutter/pull/37192
修复了 issue 47108: 在 iOS 上播放动画时的内存泄漏
https://github.com/flutter/flutter/issues/47108
DevTools 添加了完整时间线模式,并支持异步和记录的追踪
PR 1241: 添加完整时间线视图
https://github.com/flutter/devtools/pull/1241
IntelliJ 插件修复了 120FPS 支持
PR 4289: 移除硬编码的刷新速率以进行 fps 计算
https://github.com/flutter/flutter-intellij/pull/4289
更多时间线追踪改进
Gerrit 127920: [时间线] 添加对 android 平台追踪中时间线异步事件的支持
https://dart-review.googlesource.com/c/sdk/+/127920
Gerrit 128200: [时间线] 支持适用于 systrace 的 vm 事件
https://dart-review.googlesource.com/c/sdk/+/128200
Gerrit 127921: 使用 systrace 记录时间线事件时支持更多同步事件
https://dart-review.googlesource.com/c/sdk/+/127921
PR 14323: 修复使用 systrace 记录事件时缺少 API 流的问题
https://github.com/flutter/engine/pull/14323
PR 14521: 可以在发布版本模式下启用支持时间线
https://github.com/flutter/engine/pull/14521
PR 14319: 修复 flutter 引擎启动时缺少时间线事件的问题
https://github.com/flutter/engine/pull/14319
PR 47742: 修复时间线摘要时长事件
https://github.com/flutter/flutter/pull/47742
Gerrit 131360: 支持时间线转化为 iOS 平台追踪
https://dart-review.googlesource.com/c/sdk/+/131360
PR 16520: 支持无限追踪缓冲
https://github.com/flutter/engine/pull/16520
PR 47419: 支持无限时间线记录器
https://github.com/flutter/flutter/pull/47419
2019 年第 3 季度已量化的改进
矩形和点变换速度提升了 1.5–5 倍
PR 37275: 优化 matrix_utils 中的 transformRect 和 transformPoint 方法
https://github.com/flutter/flutter/pull/37275
MatrixUtils_affine_transformRect_iteration 速度提升至 5.3 倍 (从 2,300 毫秒缩短至 430 毫秒)
MatrixUtils_affine_transformPoint_iteration 速度提升至 1.5 倍 (从 466 毫秒缩短至 320 毫秒)
贡献者: flar、yjbanov、dnfield
https://github.com/flar
https://github.com/yjbanov
https://github.com/dnfield
iPhone X/Xs 滚动时丢失的帧数减少 N/2–1
https://github.com/flutter/engine/pull/12385
PR 12385: 再处理 "iOS 不规则输入事件交付"
https://github.com/flutter/engine/pull/12385
将滚动 N 个帧时丢失帧的数量 (最糟糕情况) 从 N/2 减少至 1。实机测试中,在修复之前平均丢失的帧数量为 N/10 个。
修复了以下得票数最多的 issue 之一:
Issue 31086: 由于不规则输入事件交付,iPhone X、Xs 设备上的滚动性能严重下降
https://github.com/flutter/flutter/issues/31086
贡献者: liyuqian、chinmaygarde、gaaclarke
http://github.com/liyuqian
http://github.com/chinmaygarde
https://github.com/gaaclarke
通过并行初始化将引擎启动和关闭时间缩短 15%
PR 10182: 通过允许对初始化进行并行处理加快了 flutter 启动速度
https://github.com/flutter/engine/pull/10182
BM_ShellInitializationAndShutdown 的速度提升至 1.16 倍 (从 3,829,377 纳秒缩短至 3,286,713 纳秒)
https://github.com/flutter/engine/pull/10182#issuecomment-531953100
贡献者: gaaclarke、chinmaygarde、liyuqian
https://github.com/gaaclarke
http://github.com/chinmaygarde
http://github.com/liyuqian
着色器预热的启动速度加快 14.57 毫秒,内存使用量减少 8MB
PR 36482: 通过仅在 100x100 表面上绘制加快了着色器预热速度
https://github.com/flutter/flutter/pull/36482
启动时读取/转换像素的时间节省了 14.57 毫秒 (从 18.848 毫秒缩短至 4.279 毫秒)
https://github.com/flutter/flutter/pull/36482#issue-299068276
启动内存中位数节省了 8MB (从 39,220KB 减少到 31,184KB)
https://github.com/flutter/flutter/pull/36482#issuecomment-531067365
结束内存中位数节省了 4MB (从 45,034KB 减少到 40,980KB)
https://github.com/flutter/flutter/pull/36482#issuecomment-531067365
贡献者: gaaclarke、liyuqian、dnfield
https://github.com/gaaclarke
http://github.com/liyuqian
https://github.com/dnfield
代码大小缩减了 1.02%-8.04%
https://dart-review.googlesource.com/c/sdk/+/118280
https://dart-review.googlesource.com/c/sdk/+/112758
https://dart-review.googlesource.com/c/sdk/+/118181
armv8 animation_bench_instructions_size 减小 8.04% (从 5.57MB 缩减至 5.13MB)
armv7 flutter_gallery_readonlydata_size 减小 2.7% (从 2.10MB 减少至 2.05MB)
armv7 layout_bench_instructions_size 减小 1.22% (从 2.10MB 减少至 2.05MB)
贡献者: johnniwinther、aartbik、rmacnak-google、jensjoha、alexmarkov、mkustermann
https://github.com/johnniwinther
https://github.com/aartbik
https://github.com/rmacnak-google
https://github.com/jensjoha
https://github.com/alexmarkov
https://github.com/mkustermann
Flutter 在 Fuchsia 上的 FPS 提高多达 2 倍;改进了帧时间安排
https://fuchsia-review.googlesource.com/c/topaz/+/280230
https://fuchsia-review.googlesource.com/c/topaz/+/286735
https://fuchsia-review.googlesource.com/c/topaz/+/300135
https://fuchsia-review.googlesource.com/c/topaz/+/306773
https://fuchsia-review.googlesource.com/c/topaz/+/306772
https://fuchsia-review.googlesource.com/c/topaz/+/307953
贡献者: dreveman、amott、rosswang、mikejurka
https://github.com/dreveman
https://github.com/amott
https://github.com/rosswang
https://github.com/mikejurka
2019 年第 3 季度已量化的回退修复
iOS 上 BackdropFilter 的速度提高 3 倍
https://skia-review.googlesource.com/c/skia/+/237904
https://skia-review.googlesource.com/c/skia/+/234413
https://github.com/flutter/flutter/pull/38814
GM_savelayer_with_backdrop 的速度加快了 3 倍 (从 110 毫秒缩短至 34 毫秒)
https://perf.skia.org/e/?begin=1567010155&end=1567104574&queries=name%3DGM_savelayer_with_backdrop%26os%3DiOS
修复了回退
https://github.com/flutter/flutter/issues/36064
贡献者: lhkbob、liyuqian、flar
https://github.com/lhkbob
http://github.com/liyuqian
https://github.com/flar
之所以能够实现这些大幅度的改进 (例如提升至 3 倍之多),除去 2019 年的努力外,老版本不尽如人意的表现可能也有所 "贡献"。我们也在此分享一些同样重大的性能回退问题的修复结果。我们对这些努力深表感激,如果没有这些工作,我们会继续面临性能不佳乃至回退的问题。当然,我们也不希望大幅度的改进令较小的提升相形见绌: 有时候性能的小幅度提升仅仅只是因为起点太高,这本是好事。
2019 年第 3 季度其他改进
DevTools 支持各种显示刷新速率 (例如 60 FPS、120 FPS 等)
https://github.com/flutter/devtools/blob/master/packages/devtools/CHANGELOG.md#018---2019-10-01
目前 VSCode 插件对项目的扫描是异步扫描,这应该会提升扩展程序激活速度并降低触发 VS Code "扩展导致高 CPU" 警告的几率。(#1840/#2003/#1961)
https://github.com/Dart-Code/Dart-Code/issues/1840
https://github.com/Dart-Code/Dart-Code/issues/2003
https://github.com/Dart-Code/Dart-Code/issues/1961
iPhone Xs 已被添加至 Flutter 设备实验室进行基准测试
https://github.com/flutter/flutter/issues/34590
结论
△ 53% 的受访者对 Flutter 表示非常满意
总体则有 92% 的受访者表示满意
得益于这些贡献,Flutter 移动端性能的满意度从 2019 年第三季度的 85% 上升到 2020 年的 92%。本文虽已尽力列出大家的贡献,但仍然可能遗漏 2019 年第 3 到第 4 季度的一些贡献。如果有任何遗漏的贡献,请随时告诉我们,我们会将其纳入下一次更新。
Flutter 2020 年第三季度调研已经开启,本次调研会重点涉及移动端和 Web 端的体验细节,以及询问您对一些动画效果的看法。扫描二维码进入调研,请注意本次调研将于 2020 年 8 月 27 日截止。
对于 Flutter 性能优化,您还有什么想法和建议吗?一起在文末微信留言区交流起来!
推荐阅读
点击屏末 | 阅读原文 | 访问 Flutter 开发者社区中文资源