作为一个拥有超过 10,000 个 Star 的前端底层可视化框架,AntV G6 拥有大量用户,因此包体积优化一直是我们关注的重点之一。在 G6 5.0 中,我们采取了多种优化措施,有效地精简了包体积,将 G6 4.0 压缩前的 1.8 MB 缩小到了不到 1 MB,效果显著。
整体降幅高达 47.6%。那么,为了实现如此显著的包体积缩减,我们具体采取了哪些措施呢?
模块化设计
G6 5.0 优化了代码架构,采用了高度模块化设计。一方面优化代码逻辑,以更低的代码量提供等同甚至更多的能力。另一方面通过合理的模块封装复用,大大降低了重复、相似的逻辑。
经过实际验证,采用新架构开发的扩展所需的代码量与 4.0 相比能够减少 10% ~ 70% 不等。使得扩展的维护以及新扩展的开发都更为容易和快速。
下面列举了一些组件在 4.0 和 5.0 中开发所需的代码行数:
| 4.0 | 5.0 | |
|---|---|---|
| Toolbar | 530 | 130 |
| Legend | 806 | 405 |
轻量级依赖
相比于 G6 4.0 所使用的 21 个依赖,G6 5.0 的依赖项精简到仅有 10 个。精简过程中我们采取了以下措施:
- 保证依赖项自底向上版本一致性,避免多版本依赖并存,减少潜在的冲突和冗余
- 采用按需安装、注册的逻辑,去除了一些非核心的依赖项。例如,我们将SVG和WebGL渲染器设为了外置选项,仅在需要时才添加,以减轻基础包的体积。
- 移除无用依赖,并将一些较少使用的功能逻辑内置,减少了外部依赖的需求
按需引入
在 G6 4.0 中,你也许会见到这种使用方式:
import G6 from '@antv/g6';
const { GADDI } = G6.Algorithm;
GADDI(
// params
)
const graph = new G6.Graph({
// options
});
这种默认导出一个对象,包含所有内容的方式,会导致构建工具不能识别哪些属性或方法被使用,从而无法进行 TreeShaking 优化。
在 G6 4.0 内部也存在类似的包引用方式,这会导致包体积增加,将一些未使用的代码逻辑也一并打包。
G6 5.0 在内部逻辑中避免了默认引入的方式,其导出项也采用了命名导出的形式。
我们强烈建议开发者采用按需引入的方式,即通过如下方式来进行引入:
import { Graph } from '@antv/g6';
const graph = new Graph({
// options
});
监控包大小变化
包体积会随着项目的持续迭代而不断变化,因此包体积大小的监测是一个长期的过程,通过将包体积监测机制继承到 GitHub Action 过程中,能够及时了解项目体积的变化。实现这种监测也非常简单,只需要借助于 size-limit 工具并配置体积限制即可,在构建完成后执行体积监测即可。
"limit-size": [
{
"gzip": true,
"limit": "300 Kb",
"path": "dist/g6.min.js"
},
{
"limit": "1 Mb",
"path": "dist/g6.min.js"
}
]
最后
G6 5.0 仍然具备着一定体积优化空间,例如一些依赖项的下级依赖导致的包体积增大,后续我们会
尝试为相关仓库提 PR 进行解决,预计还能降低 8%(~150Kb)的包大小。