webpack 性能优化
- 生产环境性能优化
- 开发环境性能优化
开发环境性能优化
- 优化打包构建速度
- HMR (css/js/html)
- html 文件一般只有一个,不需要做
- js 文件默认是不支持的,需要自己写
- css 文件 经过 style-loader 处理,默认是做好的,所以我们也不需要操心
- HMR (css/js/html)
- 优化代码调试 (分为生产环境和开发环境两种)
- source-map 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了, 通过映射可以追踪源代码错误)
生产环境优化
- 优化打包构建速度
- oneOf
- 缓存
- babel 缓存(第二次构建时会快一些)
- 持久化缓存
- 优化代码运行的性能
- 缓存
- hash : webpack 打包时每次都会生成一个唯一 hash 值(不管文件是否变化)
- chunkhash: 来自于同一个 chunk(打包来自同一个入口,同属于一个 chunk,例如 css 文件也是来自于 js 文件引进来的,所以 css 文件和 js 文件的 hash 值也是一样的。一旦 js 文件变化, css 文件的 hash 值也会变化),共享同一个 hash 值
- content-hash: 根据文件内容生成 hash 值(文件内容不同, hash 值一定不一样)
- tree shaking(树摇)
- 咋们整个业务程序是一棵树,我们引用的代码,引用的库里面的一些内容它们是我们树上的绿色的鲜活的树叶,而我们没用的代码,没用的库,对于我们代码而言是树上的灰色的枯萎的树叶。一旦我们把这棵树摇晃起来,那么这些枯萎的树叶就会落下来,自动清除掉。
- 所以 树摇 的概念就是去除我们应用程序中没有使用的一些代码,从而使我们的代码体积更小。
- 必须开启 es6 模块化才能开启树摇。
- 使用 webpack 的生产环境,树摇功能默认启动(内部会去使用 uglifyjs 去压缩代码,压缩代码的时候会自动清除未经引用的代码)
- 树摇还可以在
package.json
中写上:"sideEffects": [xxx] // 写上不想删除的文件(比如样式文件)
- code split (代码分割)
- 单入口场景
- 单入口场景默认输出只有一个
bundle
(所有的 js 文件默认会被打包成一个文件输出出去,如果有 10000 个 js 文件,代码体积就会非常大,需要进行代码分割,将一个大的bundle
文件拆分成很多小的 js 文件) - 两种拆分方式
- 通过
optimization: { splitchunks: 'all' }
配置,将node_modules
里面的东西单独打包成一个chunk
- 还可以通过
import
语法对指定的 js 代码进行分割,只要 js 代码是通过import
引入的,那么一定会分割成单独的文件。所以通过import
语法就可以对代码进行分割了。
- 通过
- 单入口场景默认输出只有一个
- 多入口场景
- 多入口就是你有几个入口就会输出几个文件(bundle)
- 多入口还是会 optimization 来提取多入口之间的公共代码成一个,如果没有 optimization 的话,那么多入口的话会重复打包重复的代码,这样就不太好了。
- 也可以使用
import
语法分割代码
- 单入口场景
- 懒加载/预加载(js 代码)
- 懒加载: 使用代码分割的技术,只要代码分割这块是在异步中执行的,那么它就会懒加载。一上来并不加载代码,等条件触发了才加载代码。如果 js 代码一上来有的代码并没有用,那么后面再加载并不影响并不影响其它主要代码的加载,这样我的主要代码加载速度就会更快一些。
- 一上来不加载,等其它资源加载完了,我再偷偷的加载。优势在于懒加载的时候是我触发的时候去加载再执行,如果文件体积较大,那么用户会感觉明显的卡顿。而预加载是等其它资源加载完,再偷偷的加载,这个时候在使用时很可能资源已经加载好了,速度就会比较快。
- 预加载感觉是比懒加载更好一些,但预加载的兼容性问题比较严重。用的时候需要慎重。(可以去 can i use 查看是否可以用)
- PWA (多进程打包,优化打包构建速度)
- serviceworker + cache 方法组成
- 作用:帮助我们去让我们的网站即使在离线的环境下也可以访问,让我们的程序
变得更加友好。 - 一般应用在消耗时间比较长的情况下(例如 babel-loader)
- externals
- 让某些文件不被打包而优化打包构建速度(首先需要声明哪些库不需要打包)
- 某些库(例如 vue)不打包,而通过 cdn 的方式直接引入库。(在 html 中通过 cdn 链接把库引进来)
- dll
- 让某些文件不被打包而优化打包构建速度
- 对第三方的库再次进行单独的打包,能够对第三方库进行再次细化。
- 我先把这个库打包好,后面直接用就好了,不再打包。
- 配置较为复杂,至少需要写两个配置文件(一个作为单独打包的 dll 配置文件,一个是我们正常运行的 config 配置文件)
- 缓存