代码啊分割
- 如果把 一个 应用的 所有代码 都打包到 一个文件,如果文件过于庞大,首次加载 会非常 缓慢,同时 加载了 没使用的 模块,因此 可以把 这些代码模块 分割成 单独一个文件,运行时 再去加载。使用webpack4.x的 splitChunksPlugin插件 可以帮助我们实现代码分割,替代了 之前的 commonsChunkPlugin插件。
参数详解
module.exports = {
mode: 'development',
// 下面这里是默认值
entry: {
// 入口文件名的键 main (下面简称 入口文件)
main: './src/index.js'
},
output: {
filename: '[name].bound.js',
path: path.resolve(__dirname, '../dist'),
},
...
optimization{
splitChunks: {
/**
1. 三个值
async 仅提取按需载入的module
initial 仅提取同步载入的module
all 按需、同步都有提取
*/
chunks: "async",
// 只有导入的模块 大于 该值 才会 做代码分割 (单位字节)
minSize: 30000,
// 提取出的新chunk在两次压缩之前要小于多少kb,默认为0,即不做限制
maxSize: 0,
// 被提取的chunk最少需要被多少chunks共同引入
minChunks: 1,
// 按需加载的代码块(vendor-chunk)并行请求的数量小于或等于5个
maxAsyncRequests: 5,
// 初始加载的代码块,并行请求的数量小于或者等于3个
maxInitialRequests: 3,
// 默认命名 连接符
automaticNameDelimiter: '~',
/**
name 为true时,分割文件名为 [缓存组名][连接符][入口文件名].js
name 为false时,分割文件名为 [模块id][连接符][入口文件名].js
如果 缓存组存在 name 属性时 以缓存组的name属性为准
*/
name: true,
// 缓存组 当符合 代码分割的 条件时 就会进入 缓存组 把各个模块进行分组,最后一块打包
cacheGroups: {
// 如果 引入文件 在node_modules 会被打包 这个缓存组(vendors)
vendors: {
// 只分割 node_modules文件夹下的模块
test: /[\/]node_modules[\/]/,
// 优先级 因为如果 同时满足 vendors、和default 哪个优先级高 就会打包到哪个缓存组
priority: -10
},
default: {
// 表示这个库 至少被多少个chunks引入,
minChunks: 2,
priority: -20,
// 如果 这个模块已经 被分到 vendors组,这里无需在分割 直接引用 分割后的
reuseExistingChunk: true
}
}
}
}
}
简单打包
// math.js
export default function(){
console.log('add')
}
// index,js
// 非 node_modules 模块
import add from './math'
// node_modules 模块
import axios from 'axios'
add()
axios({})
// 修改配置
minSize: 1, //因为 math.js 文件过小 表示 大于1字节 就做代码分割
minChunks: 2, // 把它去掉 即不做限制
// 打包结果
default~main.bound.js 221 bytes // math.js 打包文件
default~main.bound.js.map 125 bytes
index.html 533 bytes
main.bound.js 1.51 KiB // 入口文件
main.bound.js.map 109 bytes
vendors~main.bound.js 14.7 KiB // axios 打包文件
vendors~main.bound.js.map 125 bytes
懒加载
- 或者说 按需加载,首次并不会 加载 全部 模块,这样可以提高首次响应的人速度。
// index.js 文件替换成这样 页面 增加一个按钮 id为 btn
// 点击 按钮 后再去加载 axios
document.querySelector('#btn1').addEventListener('click', function(){
import('axios').then(() =>{
console.log('懒加载 axios')
})
})
结果
prefetching 和 preloading
prefetching
- 当我们 使用 某个功能 再去加载响应的 模块,无疑也会 消耗一定的性能,如果能做到 当核心 代码加载完毕,偷偷的去加载 这些暂时还没用到的 模块,当使用到该模块 直接从缓存读取资源。没错 prefetching 可以帮助我们做到。
// index.js 文件替换成这样 页面 增加一个按钮 id为 btn
document.querySelector('#btn1').addEventListener('click', function(){
import(/* webpackPrefetch: true */'axios').then(() =>{
console.log('懒加载 axios')
})
})
结果
preloading
- 把 /* webpackPrefetch: true / 修改为 / webpackPreload: true */,preloading的模块 与 核心模块 一起加载,会消耗 首次加载的 性能。而 prefetching 相反。
说明
- 这里面 还有很多 细节问题,只有用多了,才会 注意 里面的 一些问题,有两个 参数 maxAsyncRequests、maxInitialRequests,虽然说 使用默认 即可,但是理解起来还是有点难,估计要结合webpack的打包原理,下次再总结一下,如有错误,恳请多多指教哈。