字节跳动在Google I/O上展示Flutter应用

发表时间: 2021-05-21 18:00

字节跳动正在使用并持续参与优化的这项技术,最近登上了Google I/O大会。


它就是Google开源的Flutter,用于客户端和前端开发的跨平台开发框架,已经在GitHub上获得了超过12万star。



Google I/O大会上,Flutter产品经理Zoey Fan在发布Flutter 2.2前,专门介绍了字节跳动的Flutter应用成果。



字节跳动有70多个App选择Flutter作为跨端解决方案。



相比Android/iOS双端开发,跨平台的Flutter可以节省约1/3的开发时间。


字节跳动累计有500多位Flutter开发者,200多位活跃Flutter开发者,不仅将Flutter应用于移动App,还积极尝试应用于Web、桌面和嵌入式。


这背后,是字节跳动在公司内所做的大量基础建设工作,还给Flutter官方开源提了几十个Pull Request(PR)。


压缩体积、优化性能,字节跳动针对Flutter做了什么?


字节跳动针对Flutter的建设要从两年前说起。


当时,字节跳动终端技术团队的同学注意到,公司不少业务都有跨平台开发的需求,但缺少一个工具来实现高效率、高性能的开发。


恰逢Google开源了Flutter,团队同学发现,Flutter不仅一次开发就能部署在安卓、iOS、Web等各端,而且有自己的渲染引擎,多端一致性比较好。


可以理解为,用Flutter做开发,一个产品的安卓、iOS、Web各端就可自动同步,不需要专门为各端重新画UI、写代码,减少了很多重复劳动。


于是,字节跳动终端技术团队开始就Flutter做大量优化,包括但不限于性能优化、应用框架、容器化、研发流程、混合工程支持等等,还对FPS、Timeline等工具做了优化。


在推动落地过程中,做Flutter团队还发现了很多个性化的问题。


Flutter作为一个框架是一定要加入安装包的,但放进去之后,用户下载的安装包体积就会变大,而且Flutter要用到Dart语言,用这种编程语言写的代码比原生代码更占空间,进一步增大了安装包的体积。


想要照顾用户体验,又想使用更先进的技术提升效率,这要怎么平衡?


Flutter团队成立了包体积优化专项,一方面做Data压缩、编译优化、Skia裁剪、BoringSSL/ICU库/文字渲染/libwebp等库裁剪来缩小安装包体积;另一方面,团队把原生代码和Dart代码比较了一下,发现在写相同业务逻辑时,Dart生成的机器码指令更多,于是就进行了二进制指令头、指令冗余、指令对齐的精简,以及StackMap和CodeSourceMap的精简。



上面的每一项都能缩减0.2~4MB,这样整个安装包都可以缩小不少。而且,这些优化都在一次次沟通中向Google工程师反馈,也为Flutter做出了开源贡献。


但功能上线之后,Flutter团队又发现了新的困扰。有一次,他们接到用户反馈:在产品界面上滑动的时候,怎么就那么卡呢?


他们打开后台看到,FlutterView在分别继承SurfaceView和Textureview的两种场景下,肉眼可见使用TextureView比SurfaceView更为卡顿。但通过官方默认的Timeline工具发现,TextureView和SurfaceView渲染绘制过程中,每一帧的UI线程和GPU线程耗时基本差不多,甚至TextureView还能快一点。


两者完全相反,令人摸不着头脑。


他们先用Flutter官方提供的性能分析工具Timeline来分析这个问题,但却始终无法发现任何异常。困扰已久,他们干脆把Timeline整个性能分析工具的源码研究了一遍,原因水落石出了:


SurfaceView的性能比TextureView更好,因为SurfaceView有自己的surface,渲染有独立的GL context,可独立跟SurfaceFlinger交互,充分利用triple-buffer机制;TextureView只是普通的view,依赖于宿主窗口的surface,每次flutter的ui和gpu线程完成后,并不会立刻被渲染到屏幕上,而是需要等待Native的主线程和renderThread来完成跟SurfaceFlinger的交互,可见渲染链路远比SurfaceView要长。


这一发现不只解决了滑动卡顿的问题,也向Flutter开源社区提了10个PR。经过这样的一系列工程基建后,Flutter在字节跳动逐渐成为更好用的框架。目前,字节跳动Flutter相关解决方案即将通过火山引擎移动研发平台veMARS对外输出,服务更多外部开发者。


从尝试到落地,字节跳动这样使用Flutter


Flutter在字节跳动的落地也是艰难坎坷的过程。


团队先选了一个成熟产品,希望在其中视频播放功能上先尝试落地。


这个功能本来是用安卓和iOS的原生代码写的,想要改成Flutter并不容易。他们努力了半年的时间,发现由于一些历史包袱的存在,难以把所有线上数据都对齐,想要把原有业务改头换面并不容易。


这时他们意识到,在成熟产品上修改原有功能,效用并不明显,Flutter的优点应该用在新开发的业务上,Flutter团队负责人说:“成熟的产品各个功能都是完善的,早就用安卓、iOS原生技术写完了,现在只是做一些调整,用Flutter重写效率也没有很大的提升,把Flutter引擎放进去还占包体积。但如果用在新的产品、新的场景里就可以大幅提高效率。”


思路转变之后,他们迅速把目光投向了教育等方向的新业务。


在教育产品「大力爱辅导」中,为了教小朋友们汉字笔顺,需要完成一项「汉字描红」功能。


要实现这个功能,大力爱辅导研发团队借助部分开源项目的思路,用SVG指令表示笔画,之后调整坐标系,在合适的位置上组成汉字:



然后找出每个笔画中关键的骨骼点,像书法一样,虚拟的笔就可以按照骨骼点来移动:



按照骨骼点的顺序,依次以骨骼点绘制出半径为radius的圆,大量的圆形组成了笔画,并补充一些关键点来保证足够的帧数。


这样,就可以得到流畅的描红效果:



这项功能就是用Flutter开发的,现在已经覆盖了9000多个汉字,支持绝大部分常用字。相比用原生代码开发,Flutter节省了更多开发的时间和精力。


现在,字节跳动许多App都用了Flutter和其他技术混合的开发方式,新的产品更倾向完全使用Flutter。在西瓜视频、抖音火山版、开言英语等多个业务上,Flutter都提升了大约三分之一的开发效率。


拥抱新技术的ByteDancer


现在,字节跳动的Flutter团队依然在持续探寻最新的技术。“我们团队有很多具有全球视野的技术热爱者,会持续发掘全球技术动态,讨论技术的落地,”团队负责人说,“我们和国内外许多技术公司都有密切的联系与合作,比如我们跟Google有一个季度会议,会定期关注Google的进展,交流想法、需求、技术idea。”


有一天,Dart的GitHub项目维护者找到字节跳动Flutter团队负责人:你们字节跳动有个同学给Dart提了十几个PR,都很不错,思路非常清晰。


Dart这个编程语言,目前最广泛的应用场景就是Flutter。


这位同学就是Flutter团队的Frank。这位刚刚本科毕业三年的同学是一位非常热心的开源贡献者,从2015年开始,还在读大一的他就开始了自己的开源之路,他主导开源的一个游戏框架在GitHub上有700+star。“之前每年都有几百次下载,有很多游戏开发者用它做demo”,他这样介绍。


毕业后,当Frank进入Flutter团队,他也成了团队中最热心的开源贡献者之一,不断给Flutter和Dart提PR。他还记得在研究安装包体积的问题时,主动跟进了一个相关的issue,发现Specializer的优化有一些可以完善的地方,就把Dart的编译器中端做进一步优化。因为涉及到的代码块比较多,来来回回改了7次,双方顺利沟通后,一个星期就merge了。


截止到现在,他已经给Dart提了18个PR,其中有10个已经被merge。


像Frank这样热衷技术开源的同学,Flutter团队还有很多。


他们这样总结这种对创新的积极态度:


这个行业里确实很多人只喜欢用成熟的技术,但任何一个新技术都有从不成熟发展到成熟的阶段,总有一些人热衷尝鲜、喜欢新技术。


尤其是对于Flutter这种「破坏式」创新,我们软件行业里总需要一些勇于挑战的人来投入。在字节跳动,不管是我们Flutter团队,还是我们服务的很多业务团队,都在积极尝鲜,愿意投入到新技术里——这也确实让我们尝到了甜头,提升了开发效率。


我们希望能做一些事情,推动行业往前走,Flutter可能就是其中之一

关注「字节跳动技术范儿」

了解更多字节跳动技术成果

字节跳动海外技术团队再夺冠:高清视频编码已获17项第一

抖音40亿播放,娜扎、唐嫣都在玩的春节道具,背后是怎样的技术

↓ 点击「了解更多」,加入字节跳动 Flutter 团队