2019 下半年 Flutter 实现的性能优化 | 英雄榜

作者 / 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 开发者社区中文资源


已标记关键词 清除标记