它是什么?

#

应用大小工具可以帮助你分析应用的总体大小。你可以使用分析选项卡查看“大小信息”的单个快照,或者使用差异选项卡比较“大小信息”的两个不同快照。

什么是“大小信息”?

#

“大小信息”包含 Dart 代码、原生代码以及应用中非代码元素(如应用程序包、资源和字体)的大小数据。“大小信息”文件包含了应用程序总大小的完整数据。

Dart 大小信息

#

Dart AOT 编译器在编译应用时(仅限 profile 或 release 模式——AOT 编译器不用于 JIT 编译的 debug 构建)会对你的代码执行摇树优化 (tree-shaking)。这意味着编译器会尝试通过移除未使用或不可达的代码来优化应用的大小。

在编译器尽可能地优化你的代码后,最终结果可以总结为二进制输出中存在的包、库、类和函数的集合,以及它们的字节大小。这是“大小信息”中 Dart 部分,我们可以在应用大小工具中分析它,以进一步优化 Dart 代码并追踪大小问题。

如何使用

#

如果 DevTools 已连接到正在运行的应用程序,请导航到“应用大小”选项卡。

Screenshot of app size tab

如果 DevTools 未连接到正在运行的应用程序,你可以从启动 DevTools 后出现的着陆页访问该工具(参见启动说明)。

Screenshot of app size access on landing page

分析选项卡

#

分析选项卡允许你检查大小信息的单个快照。你可以使用矩形树图和表格查看大小数据的层级结构,并且可以使用支配树和调用图查看代码归因数据(例如,为什么某个代码片段会包含在你的编译应用中)。

Screenshot of app size analysis

加载大小文件

#

当你打开分析选项卡时,你会看到加载应用大小文件的说明。将应用大小文件拖放到对话框中,然后点击“分析大小”按钮。

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:d 链接到其直接调用者 package:bpackage:c,而不是其“支配者” package:a

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

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

Screenshot of code size call graph

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

#

如果你想了解某个代码片段为何包含在你的应用程序中的根本原因,请使用支配树。如果你想了解某个代码片段的所有调用路径(传入和传出),请使用调用图。

支配树是对调用图数据进行分析或切片的结果,其中节点通过“支配”而不是父子层级关系连接。在父节点支配子节点的情况下,调用图和支配树中的关系是相同的,但这并非总是如此。

在调用图完整(每对节点之间都存在一条边)的情况下,支配树会显示 root 是图中每个节点的支配者。这是一个调用图能让你更好理解为什么某个代码片段会包含在你的应用程序中的例子。

差异选项卡

#

差异选项卡允许你比较两个大小信息的快照。你正在比较的两个大小信息文件应该来自同一个应用的不同版本;例如,代码更改之前和之后生成的大小文件。你可以使用矩形树图和表格可视化这两个数据集之间的差异。

Screenshot of app size 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 文件导入应用大小工具以进行进一步分析。有关更多信息,请参阅应用大小文档

其他资源

#

要了解如何使用 DevTools 对 Wonderous App 进行逐步大小分析,请查看应用大小工具教程。文中还讨论了各种减小应用大小的策略。