前言

作为一个多端开发框架,Taro 从项目发起时就已经支持编译到 H5 端。随着 Taro 多端能力的不断成熟,我们对 Taro H5 端应用的要求也不断提升。我们已经不再满足于“能跑”,更希望 Taro 能跑得快。

我们经常收到用户反馈:为什么使用 Taro 脚手架创建的空项目,打包后代码体积却有 400KB+;也有用户在 Issue 中提到,Taro 的部分 Api 占用空间巨大,事实上功能却并不完美,等等。作为一个开源项目,我们非常重视社区开发者们的意见。所以在最新版本中,我们对 Taro H5 端的性能表现进行了优化。

作为运行时的基础,每一个 Taro 的 H5 端应用都需要引入 @tarojs/components 和 @tarojs/taro-h5 等基础依赖包。在编译、打包之后,这些依赖包大约会在首屏占用 400KB 以上的空间。如果开发者还使用了 UI 库,例如 Taro-UI,基础体积还会更大,这严重限制了 Taro H5 端应用的性能优化空间。

事实上,我们在 H5 端应用中并不会使用到全部的 Taro 组件和 Api。将这些依赖包全部打包进应用是没有必要,也是不合理的。进行死码删除(Dead code elimination),进一步缩减代码体积,就是我们的优化方向之一。

效果

在介绍具体细节之前,我们先看一看优化的效果,因为这可能会让你更有兴趣了解后面的内容。用一句话来说,效果非常显著。

我们建立了一个空项目,在项目配置中加入了webpack-bundle-analyzer插件以查看编译分析。下图是优化前的打包文件分析结果:

before

而在优化后,对比非常明显:

after

优化前生成的代码总大小为 455KB,而在优化后仅剩约 96KB,仅是原来的 1/5 左右。

你需要做什么

很简单,作为使用者,你不需要做任何代码上的改动,只需要将 Taro 更新到最新版本即可。但在看不见的地方,Taro 却默默地做了许多工作。下面会从原理出发,详细介绍 Taro 的工作。

原理

死码删除(Dead code elimination)是一种代码优化技术,可以删除对应用程序执行结果没有影响的代码。Web Fundamentals 的一篇文章有提到,treeshaking 是由 Rollup 提出的一种死码删除的形式。

Tree shaking is a form of dead code elimination. The term was popularized by Rollup, but the concept of dead code elimination has existed for some time.

Reduce JavaScript Payloads with Tree Shaking, Jeremy Wagner

通过在构建时进行静态分析,编译工具可以分析出我们代码中真正的依赖关系。treeshaking 把我们的代码想象成一棵树,代码的每个依赖项看作树上的节点。将未使用过的依赖项从构建结果中移除,这就是 treeshaking 的基本思想。

那么,假设我们手头有一段代码,我们要怎样辨别其中可以删除的部分呢?答案是,通过分析副作用:

1
2
3
4
5
6
7
8
9
10
11
12
// add.js
export default function adda, b{ return a + b; }

// add2.js