Flutter Engine 调优系列 (二) – 二进制库瘦身 以及 Flutter 裁剪
flutter engine 本身生成的库 ( ios 对应 Flutter.framework , android 对应 libflutter.so ) 体积比较大,因此我们希望给 engine 本身做一下裁剪,在这一过程当中我们开发了一些工具辅助我们进行这类需求的完成。
linkmap 树状分布
编译工具里面的 ld linker 工具可以通过设置 -Xlinker -Map -Xlinker /path/to/xxx.output.linkmap 参数来生成 linkmap 文件,里面会记录 二进制库 代码段, 数据段 的分布,我们可以根据这些分布来评估每个模块的占用量,给后续裁剪工作提供一个指向性的目标。
工具分析完 linkmap 之后最终采用 树状图 的方式对模块占用大小进行展示,一目了然,效果如下方所示。
- Flutter.framework 的构成
- libflutter.so 的构成
linkmap 文件简介
linkmap 里面会详细记录某个地址区间的信息,[地址, 大小] -> [函数名(变量名),源文件名,二进制库section名,… ],我们只需要按照 linkmap 文件构成去解析获取这些信息,便可以去做一些定制化的聚合统计工作,比如按照 源文件名 当中的目录结构去生成 树状分布图。
- ios linkmap
1 | # Object files: |
1 | Object files :记录所有的源文件名; |
- android linkmap
1 | VMA LMA Size Align Out In Symbol |
android linkmap 构成比 ios linkmap 简单许多,每一行都记录了 5 个元信息,[地址,地址,大小,位对齐,二进制库section名/源文件名/函数名(变量名)],解析相对简单。
裁剪 boringssl
在树状分布图当中可以看到 boringssl 模块占用了 7 % 左右的大小,属于大小占用较多的 top 模块之一,这个模块在 flutter engine 当中主要给 socket 提供 ssl 的服务,包括证书校验,ssl 握手等等,在 app 当中主要是用于 https 请求的处理,而一般 app 里面都已经有成熟的 http 组件,所以我们可以裁剪掉这个模块,使用 app 的 http 组件代替这部分功能。
1 | 这个裁剪思路由 头条 率先提出,感谢。 |
- DART_IO_SECURE_SOCKET_DISABLED
flutter engine 层通过这个宏可关闭 boringssl 相关功能,接着再移除 boringssl 依赖,修改编译参数即可。
拓展
此外还可以结合 flutter engine 代码覆盖率信息进一步提供裁剪的方向,具体做法会另外开一篇文章介绍。