使用应用体积工具

这是什么?

应用程序体积工具可让您分析应用的总体积。您可以使用 Analysis 标签 来查看「体积信息」的单个快照,或使用 Diff 标签 比较使用「体积信息」的两个不同快照。

什么是“体积信息”?

「体积信息」包含 Dart 代码、原生代码和非代码部分(比如应用包,资源和字体)。一个「体积信息」文件包含您应用的所有图片数据。

Dart 体积信息

Dart AOT 编译器会在编译应用程序时对代码进行摇树优化(仅限 profile 或 release 模式 - AOT 编译器不用于 debug 生成,debug 模式是 JIT 编译的)。这意味着,编译器会尝试删除未使用或无法访问的代码,对应用体积进行优化。

当编译器尽全力优化您的代码后,产出的二进制文件会包含依赖、库、类和函数的集合,以及他们的体积(以字节为单位)。这是我们可以在应用体积工具中分析的 Dart 部分的「体积信息」, 有了这些信息,我们便可以进一步优化 Dart 代码,并且跟踪体积问题。

如何使用

如果 DevTools 已经连接到了一个正在运行的应用,点击 “App Size” 标签。

Screenshot of app size tab

如果 DevTools 未连接到应用,您可以从启动 DevTools 后出现的登录页访问该工具(查看安装说明)。

Screenshot of app size access on landing page

分析标签页

「分析」标签页允许您检查体积信息的单个快照。您可以看到层次结构的树状图和表格,并且可以使用 “dominator tree” 和 “call graph” 看到代码的属性数据(例如:为什么编译后的应用程序中包含一段代码)。

Screenshot of app size analysis

读取一个体积文件

当您打开分析标签页时,您可以看到加载一个体积文件的使用说明。拖动一个尺寸文件到弹框中,并点击 “Analyze Size”。

Screenshot of app size analysis loading screen

查看 生成体积文件 可以得到有关生成尺寸文件的信息。

树状图和表格

树状图和表格可以查看您的应用体积的结构化数据。

使用树状图

树状图是数据结构的可视化表示。在视图中,空间被分解成矩形,其中每个矩形的体积和顺序由一些定量变量决定 (在本例中,体积以字节为单位)。每个矩形的面积与节点在编译后的应用程序中所占的大小成比例关系。在每个矩形(称为 A)的内部,还有更多的矩形存在于数据层次结构的更深层(A 的子级)。

要查看树状图中的单元格的详情,请选择这个单元格。这将重新确定树的根节点,以便选中的单元格作为树状图中新的根节点。

如果要后退或向上导航,请使用树映射顶部的面包屑导航。

Screenshot of treemap breadcrumb navigator

支配树和调用图

这个部分显示了代码的体积属性信息(例如:为什么编译后的应用程序中包含一段代码)。这些数据以支配树和调用图的形式呈现。

使用支配树

支配树 是一个树形结构的图表,其子节点可以立刻被支配。如果通往 b 的每条路径都必经节点 a,那么我们可以说:节点 a 支配了节点 b

把它放在应用程序大小分析的上下文中,想象一下 package:a 导入了 package:bpackage:c,并且 package:bpackage:c 都导入了 package:d

package:a
|__ package:b
|   |__ package:d
|__ package:c
    |__ package:d

在这个例子中,package:a 支配 package:d,所以这个支配树看起来像是这样:

package:a
|__ package:b
|__ package:c
|__ package:d

这些信息对于您而言,可以帮助您理解编译后的应用程序中为何出现某些代码片段。例如,如果您正在分析应用程序的体积,并发现编译后的应用程序中包含意外的包,则可以使用支配树来跟踪包到其根源。

Screenshot of code size dominator tree

使用调用图

调用图提供了与支配树相似的信息,帮助您理解编译后的应用程序中为何出现某些代码片段。它并不像支配树一样提供了一对多的代码体积数据节点,而是展示了代码体积数据的节点之间存在的多对多关系。

我们再来看下面这个例子:

package:a
|__ package:b
|   |__ package:d
|__ package:c
    |__ package:d

此数据的调用图会将直接调用者 package:bpackage:cpackage:d 链接到一起,而不是它的「支配者」 package:a

package:a --> package:b -->
                              package:d
package:a --> package:c -->

这些信息对于理解代码片段(包、库、类和函数)之间的细粒度依赖关系非常有用。

Screenshot of code size call graph

我应该使用支配树还是调用图?

如果您想理解应用程序中包含一段代码的 根本 原因,请使用支配树。如果您想理解一段代码之间的所有调用路径,请使用调用图。

支配树是调用图数据的分析或切片,其中节点是通过「支配」而不是父子层次结构连接。在父节点支配子节点的情况下,调用图和支配树中的关系是相同的,但情况并非总是如此。

在调用图完成的情况下(每对节点之间存在一条边),支配树将显示出 root 是图中每个节点的支配者。调用图可以让您更好地理解为什么在应用程序中包含一段代码。

差异标签页

diff 标签页让您可以比较体积信息的两个快照。您要比较的两个体积信息文件应该从同一个应用程序的两个不同版本生成,例如,在更改代码之前和之后生成的体积文件。您可以使用树状图和表格可视化两个数据集之间的差异。

Screenshot of app size diff

读取体积文件

当您打开 Diff 标签页时,您将看到加载「旧」和「新」大小文件的使用说明。同样,这些文件需要从同一个应用程序生成。将这些文件拖放到各自的对话框中,然后单击 Analyze Diff

Screenshot of app size diff loading screen

查看 生成体积文件 可以得到有关生成这些文件的信息。

树状图和表格

在差异视图中, 这个树状图和表格只会显示导入的两个文件中的差异数据。

关于树状图的问题,可以查看使用树状图

生成尺寸文件

要使用应用体积工具,您需要生成一个 flutter 体积分析文件。此文件包含整个应用程序的体积信息(本机代码、Dart 代码、资源和字体等),您可以使用 --analyze size 标志生成它:

flutter build <your target platform> --analyze-size

这会构建您的应用并输出尺寸的摘要到命令行,同时告诉您在哪里找到体积分析文件。

flutter build apk --analyze-size --target-platform=android-arm64
...
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
app-release.apk (total compressed)                               6 MB
...
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
A summary of your APK analysis can be found at: build/apk-code-size-analysis_01.json

在这个示例中,想要进行更进一步的分析,可以导入 build/apk-code-size-analysis_01.json 文件到体积分析工具。更多信息,可以查看 应用体积尺寸文档

其他资源

若你想要了解对应用(例如 Wonderous)进行包体积分析的详细步骤,可以阅读 应用体积工具介绍。教程内也讨论了多种减少包体积的方法。