1. 前言
对于一个网站来说,网页加载的快慢是关乎用户体验的一个很重要的指标。一般在项目上线前,我们要利用打包工具对整个项目进行打包,将代码进行合理的编译,产生一份生产环境的代码。刚开始,为了减少资源的请求数量,通常我们将项目代码打包成一个js文件;但是如果这个js文件很大的话,就会导致加载的时间较长,影响体验。这时候我们就需要将代码进行分离(Code Splitting),变成很多块,在需要的时候在去加载,同时结合浏览器的缓存,可以明显的加快网页的加载速度。
2. 🌰
以webpack打包单页应用为例进行分析,通常我们打包的代码包括两部分
- 代码中用到的并且很少更改的依赖包,通常文件比较大(vendor.js)
- 业务代码,改动很频繁,文件比较小(main.js)
这里省略N步,假设我们的demo目录结构如下:
其中webpack.config.js配置
|
|
在index.js这个入口文件中,我们引用了一个依赖(lodash,假设它比较大)。为了方便分析,webpack.config.js中添加webpack-bundle-analyzer这个插件。
|
|
编译一下:
可以看到main.js里面包含了lodash这个第三方依赖,我们假设index.js需要的是多个依赖,那么main.js将是巨大的,很影响项目页面加载。下面尝试一下将lodash分离到vendor.js,进行Code Splitting。
3. 方法
- 分离业务代码和第三方依赖
- 按需加载
1) 分离业务代码和第三依赖
先说第一种,接着上面的例子,我们多添加一个entry
|
|
编译如下:
可以看到vendor.js这个打包后的文件包含了我们想要的lodash.js,但是同时main.js也包含了。
这是因为每个entry都包含了它自己的依赖,这样它才能作为一个入口,独立地跑起来。下面我们要做的就是把vendor.js和main.js相同的依赖提取出来,这里我们需要配置一下optimization(由于这个例子用的文webpack版本是4.24.0,不支持CommonsChunkPlugin,4.0以下版本需使用CommonsChunkPlugin):
|
|
编译如下:
可以看到,这时main.js只包含index.js,而较大的lodash.js被分离到了vendor.js里面。
当所需的依赖非常多时,我们可以通过下面的配置:
来把来自node_modules目录结尾的第三方依赖移到vendor chunk里去,而不是在entry的vendor下配置一大串需要分离到vendor的依赖。
2) 按需加载
在前面的index.js中,我们采用的是
|
|
这样静态导入lodash,现在我们采用import()来动态导入依赖,并且多引入了axios这个第三方依赖来比较:
|
|
编译如下:
可以看到,两个依赖包分别被打包到1.[hash].js和2.[hash].js,main[hash].js也只包含index.js。另外由于import()返回的是promise,所以还可以配合async函数使用。
3.总结
Code Splitting利用了webpack-bundle-analyzer进行分析,将项目中用到的较大的第三方依赖包,公共部分等抽离处理,打包到其他单独的文件,由于该文件一般改动的几率不大,可以利用浏览器的将其缓存,达到加快加载速度的目的。
~
~
~
完
~
~
~
如有错误,还望指出。
参考链接:
webpack官网代码分离
饿了么前端知乎