Flutter轻量引擎实践

如果无法正常显示,请先停止浏览器的去广告插件。
分享至:
1. Flutter 轻量引擎实践 字节跳动 Flutter 生态分享 侯华勇 就职于字节跳动 Flutter Infra 团队,主要负 责 Flutter 引擎优化、稳定性建设、以及基 础设施搭建等相关工作。
2. 01 Flutter 多引擎背景介绍 02 Flutter 轻量引擎实现原理 03 轻量引擎相关问题 04 轻量引擎后续进展
3. Flutter 多引擎背景介绍 目前在混合工程中集成 Flutter 业务主要有两种场景,以整⻚方式来进行 Flutter 展示和在一个⻚面中嵌入多个 Flutter Item,我们 通常的处理方式是复用同一个引擎或者创建多个引擎来进行展示。 NativeView Navigator FlutterView FlutterView NativeView FlutterView FlutterView
4. Flutter 轻量引擎实现原理
5. Flutter 轻量引擎实现原理
6. Flutter 轻量引擎实现原理 内存占用 官方数据:双端新增Engine都仅需180KB. https://flutter.dev/docs/development/add-to-app/multiple-flutters 实测Android新增一个Flutter卡片,内存增量~0.8M;iOS新增一个FlutterVC,内存增量~3.8-4.8M(后续可优化至 ~500K) FlutterView数量 2 3 4 Android内存值 68.8 69.6 70.5 iOS内存值 39.3 42.7 47.6
7. Flutter 轻量引擎实现原理 启动速度 Android:速度提升~2.63倍 iOS: 速度提升~9倍 安卓以 FlutterFragment 形式新增卡片,统计为Engine开始创建到 onFlutterUIDisplayed 普通方式创建 EngineGroup创建 Android 耗时 140~150ms 50~60ms Android 耗时 iOS 耗时 280~300ms 30~40ms iOS 耗时
8. 轻量引擎相关问题 • 引擎之间的数据同步 • imageCache共享问题 • ⻚面不可⻅时的内存处理 • FlutterView 自适应宽高
9. 轻量引擎数据同步 由于多引擎是利用 Dart 的 IsolateGroup,相比之前没有 IsolateGroup 的情况,内存和启动速度上都有很大的提升。然而多个引 擎虽然在同一个 IsolateGroup 中,并且使用的是同一个 Heap,但 Isolate 之间的数据仍然是不共享的。
10. 轻量引擎数据同步 使用MethodChannel实现 在业务实现过程中,多个⻚面之间进行数据共享是一个非常常⻅的述求,最普遍的场景就是用户信息,Isolate 之间的数据 是不共享的,通过 MethodChannel 可以在引擎之间进行数据同步达到这个目的,但是使用 MethodChannel 会有一些问题 1、首先需要每一端都要书写相应的 Native 实现; 2、其次是 MethodChannel 在传递数据的过程中会进行序列化,性能会有损耗。
11. 轻量引擎数据同步 Dart 的 Isolate可以通过 Port 的方式进行通信,我们可以借助这项机制来实现多个Isolate之间的数据同步。 • 将需要共享数据收敛到一个 ServiceIsolate 中,这样共享数据还在 Dart 层,不再需要考虑多端的问题; • 进行更新的时候,发送消息到 ServiceIsolate 中,此时 ServiceIsolate 将更新的消息广播到其他的 Isolate 中; • 获取最新数据的时候,向 ServiceIsolate 发送一条请求消息,ServiceIsolate 在收到消息之后将数据再发送回来; • 通过 FFI 进行 Isolate 间 Port 的绑定,可以直接在不同的 Isolate 之间传递 Dart 对象,避免序列化和反序列化。
12. 轻量引擎数据同步 数据同步的使用方式
13. 轻量引擎图片缓存 imageCache 数据之间的共享问题 • • 图片内存不共享,同一张图片在多个 Engine 中显示需要重复解码,重复占用内存 每个 Engine 默认有 100M 的 ImageCache,如果不共享,可能出现不同引擎利用率差异大的问题
14. 轻量引擎图片缓存 imageCache 数据共享方案
15. 轻量引擎内存销毁 ⻚面不可⻅释放内存 官方对外说明额外创建一个卡片引擎内存增量~180K,在实测的过程中 iOS 每多创建一个引擎的内存增量在4-5M。为什么会产生这么大的差异呢 使用 Instrument 获取内存增⻓详情的过程中,从官方的 Demo 中不断的 Push 进入新的轻量引擎界面,可以看到里面内存占用比例最高的部分是在进行渲染 过程中产生的缓冲区,这个所需内存块的大小取决于屏幕分辨率以及创建出 FlutterView 的 ViewportMetrics。
16. 轻量引擎内存销毁 ⻚面不可⻅释放内存 使用 Instrument 进行多次 Push 之后的内存占用情况如上图,在下一次 Push 的时候上 一个⻚面内存占用大大降低,使用此方案之后除去当前展示⻚面中的 Surface 占用,每 新增一个⻚面的内存增量由原来的5M,减小到~500K。
17. FlutterView 宽高自适应 轻量级引擎使用方案使 Flutter 可以更方便应用到列表 Item、Banner 等场景中,但是在使用 FlutterView 过 程中由于父布局的限制,Flutter 内容只能充满父布局,无法根据具体的内容进行自适应的布局,这使得该 方案在一些常规场景中有一些问题。
18. FlutterView 宽高自适应 • • 在获取整个Flutter布局的时候我们需要修改 FlutterView 尺寸变更的通知流程,先给 Dart侧 一个足够大的Size,保证 Dart 在 布局的时候能够测量出正确的结果; 然后在监听 Dart 侧的布局,获取宽高通知给 Native;
19. FlutterView 宽高自适应 如果在⻚面中存在图片,由于 Dart 侧需要多次 Layout 才能获取到准确的宽高值,而在获取到最终的宽高之前,不能修改父布局的尺寸,否则父布局的尺寸 变动会同步到 Dart 侧然后影响到 Dart 侧的布局。 获取到解码 _image 信息之前,测量的逻辑是 ImageWidget 有设置宽高就使用设置的宽高,没有设置宽高就是使用最小值。似乎要求业务方在自适应布局的 场景中指定图片的宽高就可以了,但是真正在代码编写的时候,这个是比较难做到的,而在一些布局中图片的宽度和高度是没法获取的。 最终我们采用要求业务方书写宽高比的方式,结合图片宽高比和 BoxConstraints 中父布局给的限制,可以在没有设置宽高,没有解码数据的情况推测出 ImageWidget 应该占用的占用大小。
20. 轻量引擎后续规划 • 多引擎之间的线程共享导致的性能问题 • 多平台下的轻量引擎适配 • 单个 isolate 中实现多窗口
21. Q&A
22. UME Kits competition 插件开发竞赛活动 UME(flutter_ume) 是一款 Flutter 应用内调试工具平台,支持插件扩展。 Pub:https://pub.dev/packages/flutter_ume GitHub:https://github.com/bytedance/flutter_ume 本次活动针对 UME 的插件开发展开竞赛,将于杭州 Flutter Festival (4.9)上正式宣布,更多活动细则我们将在字节跳动 Flutter 技术交流群 中推送,欢迎扫码加入。 字节跳动 Flutter 技术交流

首页 - Wiki
Copyright © 2011-2024 iteam. Current version is 2.137.3. UTC+08:00, 2024-11-25 14:49
浙ICP备14020137号-1 $访客地图$