Skip to main content

打包产物分析报告

overview

大体上来说,打包产物分析报告 会从多个角度展示打包产物的细节信息,从资源文件信息到第三方依赖等等。所有的信息都能在性能优化过程中起到关键作用。

术语​

在开始之前,有一些术语需要先介绍一下:

Entry Points​

前端项目打包工具通常是可以设置多个 Entry Points 的,所以我们在分析产物时,会将 Entry Points 隔离分析,获得各个 Entry Point 最精确的结果。如果打包产物包含了多个 Entry Points 的内容,可以在分析报告的顶部下拉框选择想要查看的 Entry Point。

基准​

Perfsee 不仅仅只是分析每一次构建,还会把他们和基准进行比较,展示出同基准相比变化的部分,比如资源体积、第三方依赖信息等。

Perfsee 总是会选择最新的发布分支分析结果作为基准,默认是 master 分支。你可以在 基础设置 中根据项目的偏好更改基准选取分支。

Diff​

选择了 Entry Point 之后,便会展示该 Entry Point 和选取的基准里同一 Entry Point 的对比信息,包括总资源体积、初始 JS 体积、初始 CSS 体积、失效缓存体积等。

所有资源文件的体积在光标移动到上面上之后都会有一个弹窗效果来展示更详尽的信息:

上图中,gzip 压缩使用压缩等级为 level 4,brotli 为默认设置,参考。体积可能与页面静态资源下载体积有出入,但是不会相差太多。

缓存失效​

在构建前端项目时,我们通常会给资源文件名加上 hash,然后这些资源放到 CDN 之后可以安全的使用一个较长的缓存失效时间。

一般来说,给文件名加 hash 的算法通常是基于 content hash。也就是说在文件内容变化之后 hash 也会随之变化,这样新版本发布之后由于 hash 不同,用户端自然会去下载新的资源文件。

功能详细说明​

功能介绍需要与截图中标记序号对应

1. Entry Points​

从这里可以切换来查看不同的 Entry Point 信息。

2. 更改基准​

可以自由切换其他构建分析结果作为想要对比的基准。点击后会弹出可选列表。

select-baseline

note

基准在打包产物上传后会立即选定并且冻结,所以在这里选择基准对比基准仅仅影响前端的展示结果。

3. 基础信息​

当前打包版本的基础信息,包括打包时间、Commit Hash、分支等信息。

4. 产物得分​

我们预定义了数个审计规则对打包产物进行打分。前往 Bundle 审计 查看这些规则和分数计算方式。

5. 产物信息概览​

展示了产物的总体积以及各个类型的资源的比例情况。

6. 初始加载 JS 体积​

并非所有的 JS 都会在用户初次访问的时候加载,有很多项目会将首屏渲染不需要的代码异步加载。这里展示的数值是当前 Entry Point 排除了那些异步加载的 JS 文件之后需要初始加载的 JS 文件体积。这个体积也依然是仅仅是 Webpack 处理后的大小,并不代表真实的网络传输大小。

光标移动到这个卡片上去之后,可以显示 gzip/br 压缩之后的参考值:

7. 初始加载 CSS 体积​

与 Initial JS Size 类似,这里是当前 Entry Point 同步加载的 CSS 的资源文件体积和。光标移动到这个卡片上去之后获取压缩后参考值。

8. 缓存失效体积​

缓存失效的资源文件体积总和。

9. 第三方包的数量​

产物中引用的第三方依赖的数量。

除了项目直接用到的依赖比如 React 或者 Vue 这种,间接依赖但是被打包进入产物的第三方包也被计算在内。

Packages 列表 还会详细展示被打包进入代码的第三方包的详细信息。

note

Perfsee 提供的第三方包信息是准确的最终被打包到产物的信息。并不是通过扫描 node_modules/package.lock/yarn.lock 计算得到的。这些信息对于优化项目打包体积有非常强的指导作用。

10. 重复的第三方依赖​

在正常情况下,Webpack 不会重复打包某一个第三方依赖。但是在一些特殊情况下可能会发生重复依赖被打包的情况: 项目直接/间接依赖了不同版本的同名包。而产生这种情况的原因有很多,Perfsee 提供了不同版本同名依赖的引用路径来帮助大家解决这个问题。

比如下面的信息:

可以看到不同版本依赖的引用路径(被哪个别的第三方包引用),这样就可以在本地查看不同的依赖版本是否可以被合并,并解决。

11. 更多细节​

我们提供了四个角度来展示更多细节,他们是:

  1. 所有用户访问页面时会下载的资源列表
  2. 所有被引用的第三方依赖的列表
  3. 所有被使用了的审计规则列表及优化建议
  4. 模块引用关系的可视化展示

Tabs​

资源列表​

按列说明如下:

名称说明
Name产物的相对路径名, 相对于 Webpack 的 output path 配置
New与基准比较是否为新文件,新文件将会影响缓存失效情况
Type同步加载还是异步加载的文件
Size文件大小, 光标移入可以查看压缩后体积
Time模拟计算的预计下载时长
Included Packages文件中包含的第三方依赖体积

更多说明​

  1. 模拟计算的预计下载时长使用数据:

    • Slow 3G: 40 KB/s
    • Good 3g: 196 KB/s
    • Regular 4G: 1.5 MB/s
    • LTE 4G: 3 MB/s
    • wifi: 3.9 MB/s
    • cable: 5 MB/s
  2. Included Packages 展示的是文件中包含的第三方依赖体积,这里是依赖真正被打包进该文件那部分的体积,并非依赖的全部体积。

    如上图中,@fluentui/react 依赖引入的总体积为 538 KB (可在第三方依赖列表中查看), 而文件 npm-36cd78e3.753182e1.js 中只包含了 494 KB,这说明其余的部分被打包进了其他文件中。

    名称前带有 (concatenated) 字样的依赖,则说明该依赖的内容被 Webpack 的 Module Concatenation 功能处理了,合并进了其他模块,我们无法获取到其被使用的真实体积。

  1. 这里没有给出与基准的对比是因为:我们认为静态资源内容的变更都会反应到文件名称上(contenthash),所以文件变更的 diff 大小只有 100%(新文件)与 0%(旧文件)两种,即便给出也没有什么意义。

第三方依赖列表​

按列说明如下:

名称说明
Name依赖名及其对应版本
Current当前版本所使用到的依赖总体积
Baseline基准版本中所使用到的总体积
Type模块加载类型(同步、异步、部分同步部分异步)
Issuers引入此模块的模块名(如有)
Notes一些提示信息,如 Module Concatenation 信息
Trace可视化的引用关系图

更多说明​

  1. 依赖名称可能会存在多个重复,那么将会以相对路径的形式展示,例如 lodash@x 和 foo/node_modules/lodash@y 意味着项目中存在多个版本的 lodash 被同时引入了产物中,其中一个是由包 foo 引入。
  2. 依赖的体积则是该依赖在所有 JS 文件中被真实引用的体积,并不一定等于依赖的全部文件体积。例如在使用了 Webpack treeshaking 的情况下,没有副作用且未被使用的引入会被擦除,我们会精确的分析未见内容,给出被引入的那一部分的体积。
  3. 模块加载类型指的是包含这一模块的所有文件的可能加载方式。鼠标悬浮会展示每种类型设计到的文件及文件中包含的该依赖的体积。
  4. 引入此模块的模块名(如有)将会展示是谁引入了该模块,这将有利于分析一些意想不到的依赖的来源。
  5. Notes 信息会展示一些额外的,不那么重要的信息。目前只有一种,是 Module Concatenation 信息,未来可能会有其他的补充。

    部分依赖的体积为 0,这说明该依赖的所有代码都被 Module Concatenation 功能合并进了其他模块,这部分体积我们无法分析得到。

  6. 引用关系图则更具象地展示了该依赖的所有引用路径

    A ----> B 表示 A 引用了 B。

依赖引用

审计​

我们设计了一些面向打包产物的分析规则,并利用这些规则对打包产物进行审计、打分。 更详细的部分查看 审计规则。

可视化​

同时我们也提供了类似 WebpackBundleAnalyzer 的工具,可以帮助我们更好的了解产物内容,可视化的依赖的引用关系。

可视化