Flutter 编译模式
在接触到Flutter后,我就在思考一个问题,作为一个跨平台方案,Flutter究竟是如何在不同的CPU架构、不同的操作系统上运行的呢,它采取了怎么的编译策略,对应平台的编译产物是什么呢?本文以Android平台为例,进行了分析整理。
一、基础说明
编程语言要达到可运行的目的需要经过编译,一般地来说,编译模式分为两类:JIT 和 AOT。
-
JIT JIT(Just In Time) 翻译为 即时编译,指的是在程序运行中,将热点代码编译成机器码,提高运行效率。常见例子有 V8 引擎和 JVM,JIT 可以充分利用解释型语言的优点,动态执行源码,而不用考虑平台差异性。这里需要注意的是,对于 JVM 来说,源码指字节码,而不是 Java 源码。
-
AOT AOT(Ahead Of Time) 称为 运行前编译,指的是在程序运行之前,已经编译成对应平台的机器码,不需要在运行中解释编译,就可以直接运行。常见例子有 C 和 C++。 虽然,我们会区别 JIT 和 AOT 两种编译模式,但实际上,有很多语言并不是完全使用 JIT 或者 AOT 的,通常它们会混用这两种模式,来达到最大的性能优化。
二、Dart编译模式
-
Script:最普通的 JIT模式,在 PC命令行调用 dart vm执行 dart源代码文件即是这种模式。
-
Script Snapshot:JIT模式,和上一个不同的是,这里载入的是已经 token化的 dart源代码,提前执行了上一步的 lexer步骤。
-
Application Snapshot:JIT模式,这种模式来源于 dart vm直接载入源码后 dump出数据。dart vm通过这种数据启动会更快。不过值得一提的是这种模式是区分架构的,在 x64上生成的数据不可以给 arm使用。
-
AOT:AOT模式,直接将 dart源码编译出 .S文件,然后通过汇编器生成对应架构的代码。
三、Flutter编译模式
-
Script:同 Dart Script模式一致,虽然 Flutter支持,但暂未看到使用,毕竟影响启动速度。
-
Kernel Snapshot:Dart的 bytecode 模式,bytecode模式是不区分架构的。Kernel Snapshot在 Flutter项目内也叫 Core Snapshot。bytecode模式可以归类为 AOT编译。
-
Core JIT:Dart的一种二进制模式,将指令代码和 heap数据打包成文件,然后在 vm和 isolate启动时载入,直接标记内存可执行,可以说这是一种 AOT模式。Core JIT也被叫做 AOTBlob
-
AOT Assembly: 即 Dart的 AOT模式。直接生成汇编源代码文件,由各平台自行汇编。包体积比较大,区分架构。
可以看出来,Flutter将 Dart的编译模式复杂化了,多了不少概念,其实主要是为了解决Flutter在开发阶段、生产阶段的不同开发需求。
开发阶段的编译模式
在开发阶段,我们需要 Flutter的 Hot Reload和 Hot Restart功能,方便 UI快速成型。同时,框架层也需要比较高的性能来进行视图渲染展现。因此开发模式下,Flutter使用了 Kernel Snapshot模式编译。以Android为例,使用如下命令编译:
flutter build apk --target-platform=android-arm64 --debug
编译完成后,具体的打包产物如下:
Flutter 构建产物分析(Android)- isolate_snapshot_data:用于加速 isolate启动,业务无关代码,固定,仅和 flutter engine版本有关;
- vm_snapshot_data: 用于加速 dart vm启动的产物,业务无关代码,仅和 flutter engine版本有关;
- kernel_blob.bin:业务代码产物;
- flutter.so:Flutter引擎;
此处和一些博客中的记录有所出入,我理解应该是Flutter在演进过程中带来的差异;
生产阶段的编译模式
在生产阶段,应用需要的是非常快的速度,所以 Android和 iOS target毫无意外地都选择了 AOT打包。以Android为例,使用如下命令编译:
flutter build apk --target-platform=android-arm64 --release
编译完成后,具体的打包产物如下:
Flutter Release模式产物
- libapp.so:业务代码产物;
- flutter.so:Flutter引擎;
此外,Flutter还又一种Profile模式,,主要用于性能分析阶段,用于分析真实设备的实际运行性能,跟Release并无太大差异,只是多了对服务扩展的支持,此处就不展开了,有兴趣的同学可以自己Google一下;