跳到主内容

使用应用大小工具

了解如何使用 DevTools 的应用大小工具。

它是什么?

#

应用大小工具允许您分析应用的总大小。您可以使用“分析”标签页查看单次“大小信息”快照,或者使用“差异”标签页比较两份不同的“大小信息”快照。

什么是“大小信息”?

#

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

Dart 大小信息

#

Dart AOT 编译器在编译您的应用程序时会执行代码树摇(tree-shaking)(仅限 profile 或 release 模式——debug 版本使用 JIT 编译,不涉及 AOT 编译器)。这意味着编译器会通过移除未被使用或无法访问的代码片段来优化应用的大小。

在编译器尽力优化代码后,最终结果可以概括为二进制输出中存在的包、库、类和函数的集合,以及它们以字节为单位的大小。这是我们可以在应用大小工具中分析的“大小信息”的 Dart 部分,从而进一步优化 Dart 代码并定位大小相关的问题。

如何使用

#

如果 DevTools 已连接到正在运行的应用程序,请导航至“App Size”(应用大小)标签页。

Screenshot of app size tab

如果 DevTools 未连接到运行中的应用程序,您可以从启动 DevTools 后显示的着陆页访问该工具(请参阅启动说明)。

Screenshot of app size access on landing page

分析 (Analysis) 标签页

#

“分析”标签页允许您检查单个大小信息快照。您可以使用树状图和表格查看大小数据的层级结构,并可以使用支配树 (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

支配树与调用图

#

页面的这一部分显示了代码大小归属数据(例如,为什么某段代码被包含在编译后的应用程序中)。这些数据以支配树和调用图的形式呈现。

使用支配树

#

支配树 (Dominator tree) 是一种树结构,其中每个节点的子节点都是该节点直接支配的节点。如果到达节点 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

使用调用图

#

调用图 (Call graph) 在帮助您理解代码为何存在于编译后的应用程序中时,提供了与支配树类似的信息。然而,调用图显示的不是支配树中那种节点之间一对多的支配关系,而是显示代码大小数据节点之间存在的多对多关系。

再次使用以下示例:

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 是图中每个节点的支配者。这便是一个调用图能让您更好地理解某段代码为何被包含在应用程序中的例子。

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

其他资源

#

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