构建顺滑自然的 Flutter 页面
如果无法正常显示,请先停止浏览器的去广告插件。
1. 构建顺滑自然的 Flutter 页面
张云龙(云从)
阿里巴巴-闲鱼-无线开发专家
2.
3. 个人介绍
13 届浙江大学硕士,前后在网易、字节、阿里任
职移动端研发。
App的孵化,网易云课堂Android讲师;字节飞书
张云龙(云从)
项目;阿里闲鱼端体验和增长方面的工作。
阿里巴巴
闲鱼技术部无线开发专家
参与过网易动态化框架,移动端标化项目,严选
在移动端框架组件方面,负责过Android端路由框
架、IOC 框架、工程模板化等;在性能优化方
面,负责过 WebView 轻量缓存优化、启动优
化、流畅度优化、包大小优化等。
4. • Flutter 流畅度优化挑战
• 列表容器和 FlutterDx 组件优化
• 性能衡量和 devtool 扩展
• Flutter 滑动曲线优化
• 性能优化建议
5. 业务复杂度的挑战
更多的视图控件
更多的视图逻辑
更多的业务逻辑
卡片的动态能力 (Flutter DynamicX)
6. 框架实现的挑战
视图控件列表滚动帧渲染流程
7. 框架实现的挑战
DevTool 检测样例
- 平均 FPS 不低
- 卡顿体感明显
卡顿 卡顿
卡顿
流畅
流畅
卡顿
流畅
8. 动态能力的挑战 – Flutter DynamicX
类 Android Layout DSL
动态下发
dx 文件 + 卡片数据
动态更新能力 统一监控能力
良好研发体感 在线编辑能力
DXComponentWidget
模板装载和数据绑定开销
Widget 动态创建开销
Widget Tree
嵌套层级开销
9. 用户体感的挑战
滑动体感和原生 App 的差异
- 相同平均 FPS 体感差异
- 相同小卡顿的体感差异
- 无卡顿时的体感差异
- 90Hz 机器上的体感差异 - resamplingEnabled
10. • Flutter 流畅度优化挑战
• 列表容器和FlutterDx组件优化
• 性能衡量和 devtool 扩展
• Flutter 滑动曲线优化
• 性能优化建议
11. PowerScrollView 设计和性能优化
• Sliver 协议封装
• 协议能力补充
• 性能优化
瀑布流布局
局部刷新
卡片分帧
滑动曲线
12. PowerScrollView 瀑布流布局
13. PowerScrollView 瀑布流布局优化
•
卡片布局-列数据缓存
•
普通卡片
横条卡片
卡片布局-分页优化:最小布局计算,最小化 GC
14. PowerScrollView 瀑布流布局优化
• 布局列数据缓存
• 分页优化
GridView FlowView
• 最小化布局 布局类型 • 最小化销毁 丢帧数 24 25
最差帧耗时 53 52
15. PowerScrollView 局部刷新优化
16. PowerScrollView 卡片分帧优化
1
1
1
2
17. PowerScrollView 卡片分帧优化
18. 延迟分帧优化思路和使用建议
React Fiber 架构
reconcile
render
vDom tree 转 fiber 数据结构
可中断可恢复
PlaceHolder:widget 宽高已知
合理设置低优队列:DXFXImageWidget
低优任务建议一帧执行不超出 10 个
19. Flutter-DynamicX 组件优化-原理详解
20. Flutter-DynamicX 组件优化-缓存优化
模板装载和数据绑定开销
Widget 动态创建开销
DxWidgetNode 缓存优化
DxWidget 缓存优化
21. Flutter-DynamicX 组件优化-独立 isolate 优化
卡顿坏帧/总帧的比例
2.21% →
1.79 %
22. Flutter-DynamicX 组件优化-层级优化
卡顿坏帧/总帧的比例
2.11% →
层级优化
1.93 %
23. • Flutter 流畅度优化挑战
• 列表容器和 FlutterDx 组件优化
• 性能衡量和 devtool 扩展
• Flutter 滑动曲线优化
• 性能优化建议
24. 线下场景- flutter benchmark
UI 线程丢帧率
SchedulerBinding UI 线程每帧耗时分位数
WidgetController Raster 线程丢帧率
Raster 线程每帧耗时分位数
25. 线下场景-基于录屏的流畅度检测
手机画面
时间轴
16.6ms
33.3ms
16.6ms
16.6ms
录屏压缩画面
图像 hash 值
1000000
1002342
1002222
1002222
10538342
10998942
26. 线下场景-基于录屏的流畅度检测
帧分布
最近 FPS
平均 FPS
帧分布均方差
大卡顿次数
大卡顿累计时间
27. 线下场景-基于 devtool 的性能检测
时间显示
耗时高亮
28. 线上场景-Flutter 高可用检测 FPS 实现原理
29. 线上场景-Flutter 高可用检测 FPS 实现原理
30. 线上场景-FlutterBlockCanary 线上卡顿堆栈检测
31. 线上场景-FlutterBlockCanary 检测过度渲染
详情页快速提问组件过度渲染问题
dirtyInfo{QuickQuestionWidget,d=95,l=77,c= 255 }
优化:setState 下沉到叶子节点
dirtyInfo{QuickQuestionWidget,d=132,l=41,c= 43 }
32. • Flutter 流畅度优化挑战
• 列表容器和 FlutterDx 组件优化
• 性能衡量和 devtool 扩展
• Flutter 滑动曲线优化
• 性能优化建议
33. Flutter 列表滑动曲线和原生曲线
34. Flutter 列表在快速滑动下的表现和优化
https://github.com/flutter/flutter/pull/77497
35. Flutter 列表在卡顿情况下的表现和优化
y=d(t) → y=y+dx(t)*((△t/16.6>1? (△t/16.6-1):1)*16.6)
36. • Flutter 流畅度优化挑战
• 列表容器和 FlutterDx 组件优化
• 性能衡量和 devtool 扩展
• Flutter 滑动曲线优化
• 性能优化建议
37. 性能优化建议
用户体感 -
UI
工具使用 -
性能数值
-
GPU
数据抖动
-
性能开销
多线程 – 任务计算优化 – 用户响应优先
关注 Flutter 社区
38. 性能分析工具使用建议
•
官方 DevTools 工具
•
•
•
Debug Flags
•
•
Timeline
CPU 燃焰图
见 debug.dart
性能日志
39. 性能分析工具自身开销
40. 卡顿优化建议
UI
GPU
setState 刷新最少 Widget 使用 RepaintBoundary 隔离频繁刷新视图
Fish Redux 数据变化才新建 state 对象 减少 saveLayer、clipRect、clipRRect 使用
高度可知时,使用 itemExtent
使用 Selector 或 Consumer 获取祖先 model
避免在动画中剪裁图像,创建Widget
用 AnimatedOpacity 或 FadeInImage 代替
OpacityWidget
使用图片替换半透明效果
避免使用带换行符的长文本
41. 使用最新 Flutter Engine
42.
43.