找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

只需一步,快速开始

字节跳动Flutter包体积缩减接近50%,速来围观

查看: 5006| 评论: 7| 发布者: seoere

??? ??С
简介:前言11 月 23 日,字节跳动技术沙龙【Flutter】技术专场 在北京后山艺术空间圆满结束。这次活动邀请到字节跳动移动平台部 Flutter 架构师袁辉辉,Google Flutter 团队工程师 Justin McCandless,字节跳动移动平台部 ...

前言


11 月 23 日,字节跳动技术沙龙【Flutter】技术专场 在北京后山艺术空间圆满结束。这次活动邀请到字节跳动移动平台部 Flutter 架构师袁辉辉,Google Flutter 团队工程师 Justin McCandless,字节跳动移动平台部 Flutter 资深工程师李梦云,以及阿里巴巴高级技术专家王树彬和大家进行Flutter干货分享交流。

本文先来介绍由字节跳动移动平台部 Flutter 架构师袁辉辉 带来的分享,它的主题内容是:《Flutter如何缩减接近50%的包体积》。去掉听不懂的专业术语,按逻辑顺序逐个梳理,选取最核心的部分进行解读,主要让大家体会视频里面的精华内容,学有所得。

字节跳动Flutter包体积缩减接近50%,速来围观

演讲作者负责 Flutter EngineDart Runtime 这两个底层方向上的一些工作。所以这篇演讲还是很有深度的。反正主要介绍了Flutter Engine Dart Runtime 如何删减,如何优化,最终把Flutter的包体积压缩到到尽可能的小,能有多小就有多小,PPT上面是一大堆C 或C++底层引擎有关的专业术语。可能一般的小伙伴都听得云里雾里。我只能用下面这个表情包表达他们的心情:

字节跳动Flutter包体积缩减接近50%,速来围观

包体积现状


包体积每上升 6MB 就会带来下载转化率降低 1%,当包体积增大到 100MB 时就会有断崖式的下跌。这是Google 2016 年公布的研究报告。随着项目的发展,包体积会越来越大,但是随着包体积的增大,用户下载意愿就就慢慢降低,包体积越大,用户下载意愿就越低,所以包体积优化必须提上日程。

字节跳动Flutter包体积缩减接近50%,速来围观

今日头条APP的现状:Android端可以动态下发,插件化框架,包体积增量约等于 0,当然其它方式也可以实现,这里就不细致探讨了。iOS端 优化前包体积是 167M,Flutter 产物占 18MB,占比超过了 10%。所以当前重点是针对iOS端的包体积优化。

引入Flutter前,使用OC写,呈现出一个线性增长关系。引入Flutter后对iOS端的包体积的增长的影响,初始增长速度极快,随着代码增多,增长速度逐渐减缓,最终趋近线性增长。

字节跳动Flutter包体积缩减接近50%,速来围观

针对每一个环节具体优化细节


下面针对每一个环节优化细节做一个详细的说明。

Dart 编译产物优化


Flutter Release产物分析

为了说明包体积优化,以下是一个覆盖一些业务功能点的Demo打包后的产物分析图:

字节跳动Flutter包体积缩减接近50%,速来围观

整个APP由APP Framework和 Flutter Framework两部分组成。

● APP Framework(可变化的):

● App:Dart代码AOT编译产物,它是动态链接库

● flutter_assets: Flutter 静态资源文件夹,包括图片,字体等

● Flutter Framework(固定值):

● Flutter: Flutter Engine,它是动态链接库

● icudll.dat:国际化支持相关数据文件


包体积优化方法

简单地说就是3个字:删、缩、挪。如下图所示:

字节跳动Flutter包体积缩减接近50%,速来围观

※ 删:删除无用代码,无用资源。可以手动删除,可以机器删除,也可以编译时删除。Flutter 有一个Tree Shaking 机制,从 Main 方法开始,逐级引用,最终没有被引用的代码,诸如类和函数都会被裁剪掉。这个就是编译时自动删除

※ 缩:比如压缩图片资源。

※ 挪:从项目工程或Packages里直接挪到远端,典型是远端下发插件或者安卓里的 App Bundle,虽然“挪”对性能来说是有损的(需要动态下发),但是包体积却大大减少。


如何“挪”?

如何“挪”的步骤如下图所示:

字节跳动Flutter包体积缩减接近50%,速来围观

移除非必要产物,动态下发:将 Dart 的编译产物(App)分成两部分:Part1Part2,然后把 Part2 挪出去;然后把 flutter_assets 这个文件夹和icudtl.dat 挪出去。最后包体积就非常小了。


Dart源码编译流程(略)

为啥要略,因为这里涉及到汇编,直接略过。我相信一般朋友们也不容易懂,我就直接跳过了。有兴趣的朋友们可以点击左下角“阅读原文”去看完整版视频。

【问】:关于“挪”的那部分,说明一下:为什么Android可以全部挪动 Dart 的编译产物(App),iOS却不可以?

【答】:加载到内存后,指令段需要赋予可执行权限,iOS无法随意标记内存可执行,instr段必须在动态库内随包下发。如下图所示:

字节跳动Flutter包体积缩减接近50%,速来围观





动态下发方案(重点学习)

挪动过程如下图所示:

字节跳动Flutter包体积缩减接近50%,速来围观

Flutter 工程编译安卓的包,会编译成 4 个snapshot文件,分别是:

isolate_snapshot_instr

isolate_snapshot_data

vm_snapshot_instr

vm_snapshot_data

这里用动态下发模式的示例来举例说明,把isolate_snapshot_datavm_snapshot_data移出来,flutter_assets也移出来。挪动前:9.2M,挪动后3.8M,如果App体积庞大,那么这个收益会更明显。

【问题1】:关于iOS32位和64位双架构问题,不可能内置两份 Zip 包。

解决思路:将引擎 Zip 包置于 APP 动态库内,App Store 可以针对动态库自动实现分架构下发,如果不知道怎么做,可以参考:Dart 的Observatory Server 的 Web 静态资源,它是整个直接打到 Dart 的运行时里的,这么好的案例,当然可以参考一下。

【问题2】:风险应对。比如:下载失败,解压失败怎么办?

解决思路:转变思路,不要假设 Flutter 一定可用;提供赢钱是否Ready的Api,业务层做好上层处理。最终实际损失= Flutter 覆盖率乘 x Flutter 功能的渗透率。包体积优化之后是所有用户都收益,而损失的只是少部分用户。如果求稳,就用内置压缩,如果激进一点,就用动态下发。(今日头条团队介绍,他们的的Flutter 覆盖率目前应该可以达到三个 9,因为我们用了内部压缩方案,你也可以使用这个,但是这个动态下发确实也值得研究和尝试一下,哪怕是小范围的测试和试用也行。)

Flutter 引擎编译产物优化


接下来是Flutter.framework这一块的优化。如图8所示:

字节跳动Flutter包体积缩减接近50%,速来围观

统一编译参数

在 Flutter 引擎编译时,安卓和 iOS 的编译参数不同,安卓是-OZ,iOS 是-OS,想追求极致包体积是需要用 OZ 的,不能用 OS。解决:只需要升级最新的 build-tools,改 OS 为 OZ


定制化编译

这块结合各个厂商、各个 APP 可能不一样,有几点可以借鉴的:

(1)移除 boringSSL,可用 Method Channel 调用源生网络库来替代 Dart Http 功能,这样性能绝对有提升,同时还能带来包体积的收益。

(2)定制化编译skia,skia里面的参数很多,其中有 3 个字节跳动团队已经试过了,去掉之后最终得到收益不到 200KB。官方有更高端的概念叫模块化编译,核心思想是把 Engine 拆成不同的Modular,根据自己的情况定制化编译。

机器码指令优化


最后一部分是最高端最偏向于底层的了,看到大佬这般骚操作,简直是惭凫企鹤、望洋兴叹、望尘莫及、高不可攀、难以望其项背、不可同日而语,各位对演讲嘉宾啧啧称羡,简直有一种外慕徙业的想法,但是终究是方案,没看到代码,最后只能是对屠门而大嚼

机器码指令优化如图9所示:

字节跳动Flutter包体积缩减接近50%,速来围观

实验证明:OC 出来的机器码就比 Dart 厉害一点。比如一个简单是示例,一个函数返回自定义的 View,函数被copy次数,直接影响了包体积大小,Dart和OC编译出来的包体积和其函数被copy次数成线性关系。其中Dart 的斜率远高于 OC。

比如做过一个简单的函数测试,反编译发现,使用OC写的代码,生成了 11 条汇编指令,但是Dart生成了32条汇编指令,Dart 的汇编指令明显比OC多了很多。这也就说明了,为什么Dart和OC生成的包体积斜率不一样的原因

【解决方案】:所有函数前 8 个都有指令对齐头,后 6 位都有对齐指令,一头一尾可以移除。中间还有 18 条指令,然后这18条指令中,有 5 条是为了做栈溢出检查(可以考虑移除),OC 没有这个指令,还剩 13 条必要指令,基本与 OC 11 条持平,也存在优化空间。请看下图:

字节跳动Flutter包体积缩减接近50%,速来围观

谷歌也在针对这个做优化,有一些已经落地,有些还在推进中。

提问环节


最后就是观众提问环节:

Q:谷歌的引擎是一直在迭代的,如果我从现代的版本开始修改引擎,以后谷歌的引擎更新了,我要不要马上跟进?

A:这个问题很多人都问过我们,在 Flutter 团队引擎不停迭代时,你的自定义引擎如何跟上节奏?这个问题是我们不需要紧跟潮流,我们挑一个稳定版本,154 做有针对性的优化,过两个月再判断一下,比如现在 191 适合不适合做适配、做迁移,如果适合,那我们就做,如果不适合,或者业务方没有紧急需求,那就不升。为什么有些团队升到 178?因为海外要支持双架构,原来的不够,只能支持单架构,那么 178 默认模式就改成 Library Mode,支持 32 位和 64 位,是为了这个事情。如果你没有这个强烈的需求,反而用自己公司内部的引擎更稳定一点。


Q:我是一名移动端研发。我们通过“挪”的方式使包体积变小了,但是用户在使用实际模块当中又要挪回来,我想问的是用户在使用某个模块时,把我们挪出去的这部分挪回来的时候,这个转场我们应该怎么去处理?或者有什么更好的方案让用户无感知的加载我们挪出去的这部分东西?

A:还是跟刚才的问题一样。这个问题对于字节跳动的 Android 研发来讲还挺司空见惯的,一个功能挪出去以后,构成插件以后,也会面临你这个相同的问题。这很简单,就判断一下插件是否存在,iOS 也要判断引擎是否存在,要么是否展示接口、是否展示功能入口。你如果一定要在启动阶段首页展示这个功能的话,那你就只能阻塞一下了。


Q:您提到有一个字节码优化的问题,刚才讲到 Dart 语言应该是运行在虚拟机上的,这个字节码优化是优化编译的中间语言?还是由 Dart 虚拟机最终生成?

A:不,它是机器,在 Release 模式下运行的是机器码。在编译器由 Dart 虚拟机生成的,但是实际运行的时候它是一个完完全全的机器码。


Q:关于刚才提到字节码指令的问题,Dart 针对你举的例子里,同一条 OC 是 11 条,Dart 是 32 条,这种情况对于我们来说,我们自己没办法做这个优化,但是实际过程中要不要尽量减少小函数,这样是不是也是一种方式?

A:实际使用中应该不会写到像我今天展示这么小的函数,应该不会直接打出一个 Int,实际使用的函数远比这个要复杂,在实际使用过程中 Dart 的代码和 OC 的区别没有今天展示的那么大,我只是为了演示冗余指令,专门挑了一个特别对 Dart 不友好的 demo,但实际上没有那么大的区别。如果已经用上动态下发模式的话,留在包里的指令段真的是非常少的一部分,我们只是追求极致把事情做到尽善尽美,但是这部分就算不优化也应该是可以接受的,我们线上已经在跑着、已经在广泛用 Flutter 了,这应该不是阻碍你发布或者采用它这个技术栈的原因。


最后给大家送一点福利,感谢大家一直以来的支持和鼓励。具体内容大家可以看看这里 ↓

在这里我分享一份私货,自己收录整理的Android学习PDF+架构视频+面试文档+源码笔记,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

如果你有需要的话,可以点赞+评论+转发关注我,然后私信我【进阶】我发给你

字节跳动Flutter包体积缩减接近50%,速来围观

字节跳动Flutter包体积缩减接近50%,速来围观

字节跳动Flutter包体积缩减接近50%,速来围观




【免责声明】本文仅代表作者或发布者个人观点,不代表SEO研究协会网(www.seoxiehui.cn)及其所属公司官方发声,对文章观点有疑义请先联系作者或发布者本人修改,若内容涉及侵权或违法信息,请先联系发布者或作者删除,若需我们协助请联系平台管理员,邮箱cxb5918@163.com(本平台不支持其他投诉反馈渠道,谢谢合作)。若需要学习以上相关知识请到巨推学院观看视频教程,网址www.jutuiedu.com。

鸡蛋

鲜花

握手

雷人

路过
已有 7 人参与

会员评论

查看全部评论>>

推荐阅读

    2020-01-29 08:32
  • 作者:qetula

    抖音账号被降权 怎么办

    在抖音的账号运营同时,突然收到被降权了然后一脸懵也不知道怎么样去解决,我们该怎么样解决呢?图片为官方的通知,遇到这种情况我们该怎么样的去解决 跟着我的文章操作起来首先先判断您的账号是否存在以下几种行为

  • 2020-01-29 08:31
  • 作者:李唐

    toplip:一款十分强大的文件加密解密 CLI 工具

    它是一款使用一种叫做 AES256 的强大加密方法的自由开源的加密工具。它同时也使用了 XTS-AES 设计以保护你的隐私数据。它还使用了 Scrypt,一种基于密码的密钥生成函数来保护你的密码免于暴力破解。-- Sk在市场上能

  • 2020-01-29 08:18
  • 作者:网络营销研究网

    word中的域是什么?如何使用一些简单域的功能?

    在word中,域简单来说是一切可以更新的东西,域尽管只有一个字,但是却像excel中的宏一样变化莫测,难以琢磨,word中的域有插入页码、时间日期、进行表格计算等70多种功能,今天就给大家介绍关于使用域进行表格计算

  • 2020-01-29 07:21
  • 作者:qetula

    新买笔记本无法激活Office?方法在此

    新购买的笔记本电脑激活Office时提示错误(0xC004F200)或无法正常激活怎么办?1月3日消息,小米笔记本官方微博解答。激活前先确保Windows系统正常激活,然后在激活2个小时之后尝试Office激活。如果遇到无法激活问题

  • 2020-01-29 06:35
  • 作者:雨轩小晴

    微盟集团捐赠1000万元 支援武汉及周边地区疫情防控

    雷帝网 乐天 1月27日报道为支持湖北省及武汉市抗击新型冠状病毒感染的肺炎疫情,微盟集团宣布通过上海市慈善基金会向湖北省以及武汉周边地区捐赠1000万元,用于采购各类急需的医疗物资。该笔捐款将优先用于湖北省急

  • 2020-01-29 06:29
  • 作者:雨轩小晴

    铭冠网安IP-guard终端安全管理软件|加密软件

    铭冠网安IP-guard防泄密解决方案怎么防止机密文档被随意扩散?IP-guard可为不同的人分配不同的文档权限,每个人都只能打开相应权限的文档。针对重要文档信息可以采用强制加密,只能在授信环境中正常使用。通过IP-gua

  • 2020-01-29 06:02
  • 作者:博尔赫斯

    抖音收到“账号评级通知”怎么办?(每个玩抖音的人都应该看看)

    现在的抖音,不仅仅是一个“记录美好生活”的短视频APP,更是一个日活跃量超过2.5亿、获取新客户的超级流量池。互联网的世界,有流量的地方就有商机,就有钱赚。所以,抖音吸引了无数的创业者涌入。但是,绝大多数的

  • 2020-01-29 04:42
  • 作者:AKENGO

    微盟集团(02013)捐赠1000万元 全力支援武汉及周边地区疫情防控

    1月27日,为支持湖北省及武汉市抗击新型冠状病毒感染的肺炎疫情,微盟集团(02013)宣布通过上海市慈善基金会向湖北省以及武汉周边地区捐赠1000万元,用于采购各类急需的医疗物资。该笔捐款将优先用于湖北省急需医疗

  • 2020-01-29 04:36
  • 作者:payne

    一键免费激活office~无限白嫖!再也不怕到期了

    Office作为使用率最高的办公软件,无论是任何职业、工作或生活中我们都离不开它。前两天给大家带来的手机版WPS Office破jie版,小伙伴们使用之后反应还不错,这不,又有很多给小编留言想要电脑端的,那么小编今天就

  • 2020-01-29 03:59
  • 作者:天空之大

    数据类型WORD和INT都是16位,那么它们有什么不同呢?

    有同事跟小编聊了聊关于PLC的数据类型的问题,其中大多数大家都很容易理解,但谈及到了WORD和INT数据类型,就有些不理解了?都是16位的,那么它们有什么不同的呢?其实,这是最基本的知识,也是对于初学者也会常出现

文章排行

TOP ARTICLES

返回顶部