11月13, 2020

Flutter中的Tree Shaking机制初探

背景

在闲鱼技术探究Flutter工程一体化的过程中,为了做到最好的开发体验,需要无缝衔接FaaS端代码与业务Flutter代码,一份代码既可以在FaaS部署,也可以直接引入在业务代码主工程中,使之真正做到工程一体。

为了实现这一目标我们对两部分代码通过RPC调用的方式实现了代码解耦,而工程解耦依赖于Flutter/Dart在编译过程中的Tree-Shaking机制。为了避免踩坑,我们需要了解,整个Tree-Shaking是怎么起作用的。本篇文章结合Flutter Engine源码对这一过程进行了简单的探究。

前置知识

Tree Shaking是一种死代码消除(Dead Code Elimination)技术,这一想法起源于20世纪90年代的LISP。其思想是:一个程序所有可能的执行流程都可以用函数调用的树来表示,这样就可以消除那些从未被调用的函数。该算法最先被应用到Google Closure Tools中的JavaScript中,然后被应用到同样由Google编写的dart2js编译器中。在Flutter中,同样有这样的Tree Shaking机制来减小最终产出的包大小。Flutter提供了三种构建模式,针对每个不同的模式,Flutter编译器对产出的二进制文件有不同优化,Tree-Shaking机制并不会在debug模式中触发。在Profile/Release模式下编译的AOT产物中,有几个比较重要的产物可以让我们更直观地看到Tree-Shaking机制在发挥作用:

  • app.dill : 这就是dart代码通过build的产物,为二进制的字节码,可以通过 strings看到里面的内容,其实就是我们dart代码的源码。

  • snapshot_blob.bin.d : 这个文件里面是所有参与编译的dart文件的集合,包括我们自己的业务代码、 pubspec.yaml中定义的三方库的代码、以及我们业务代码中import进来的所有flutter或者dart原生 package的代码。

本文链接:https://blog.jnliok.com/post/884dE3GkC2FdvlPADlXc.html

-- EOF --

Comments