在最开始的时候,webpack都是将全部的代码打包到一个文件中,可是当项目过大的时候,页面所须要加载的时间就会变长,这个时候咱们就须要Code Splitting
对文件进行分块,实现代码的按需加载。node
接下来咱们来看看下面两种方式:webpack
当用第一种方式的时候, 咱们须要等打包文件加载完成以后,才会去实现文件里面的逻辑,再将页面展现出来。那么这样带来的问题是什么呢,有一个问题想必你们都很清楚,那就是打包文件很大,加载时间很长。web
那还有一个问题是什么呢,咱们都知道,lodash是一个第三方库,咱们不会随便去修改它,可是业务逻辑是常常会被改变的。假设咱们修改了业务代码,那咱们就须要从新去加载打包中的js文件,才能获取到最新的代码,显示最新的内容。由于业务代码和第三方库都在同一个文件中,因此lodash相应的也要被从新加载。缓存
index.jsapp
// 同步逻辑
// 第一种方式
// 首次访问页面的时候, 加载main.js 2mb
// 当业务逻辑发生变化时 又要加载main.js 2mb的内容
import _ from 'lodash' //假设1mb
// 业务逻辑 1mb
console.log(_.join(['a','d','c'], "***"));
// 中间省略几千行代码....
console.log(_.join(['a','b','c'], "***"));
复制代码
第二种方式咱们将上面代码拆分红了两个文件main.js
和lodash.js
,咱们将不须要修改的第三方库拎出来放在一个单独的文件中,当页面业务逻辑发生变化的时候,只须要加载main.js页面就能够了。异步
这种动态加载的方式就能提高咱们页面展现的速度,相应的也提升了性能。async
index.js性能
// 第二种方式
// main.js被拆成lodash.js(1Mb), main.js(1mb)
// 当业务逻辑发生变化时,只要加载main.js便可(1MB)
// 业务逻辑 1mb
console.log(_.join(['a','d','c'], "***"));
console.log(_.join(['a','b','c'], "***"));
复制代码
lodash.js学习
// 加载了lodash,而后将lodash挂载到了全局上面
import _ from 'lodash'; //1mb
window._ = _
复制代码
Code Splitting
其实本质上是和webpack没有任何关系的,但为何只要一说到webpack,咱们在不少时候都能听到webpack里面有Code Splitting
呢?这是由于webpack里面有一些插件能够很是容易的帮助咱们实现Code Splitting
。ui
在webpack4里面有一个插件splitChunksPlugin,这个插件直接与webpack作了捆绑,不须要安装,直接就能够拿来用了。这样的话咱们进行代码分割就很是容易了。
同步代码分割
咱们先将以前的lodash.js
和index.js
合并,而后咱们在webpack.config.js
里面配置一个optimization
:
optimization: {
splitChunks: {
chunks: 'all'
}
}
复制代码
咱们从新对代码进行打包,查看dist目录:
咱们能看见,只要作一个很是简单的配置,就能实现代码分割,彻底不须要咱们再手动进行文件的拆分。
异步代码的分割
上面咱们说的是同步加载。那么接下来咱们看看异步加载吧!
// 异步加载lodash
function getComponent() {
return import('lodash').then(({default: _}) => {
const element = document.createElement('div')
element.innerHTML = _.join(["linna", "mao"], '-')
})
}
getComponent().then(element => {
document.body.appendChild(element)
})
复制代码
若是你们实践过的话,就知道即使咱们不在webpack.config.js
中配置optimization
,异步载入的组件也会自动打包再一个单独的文件中。
从上图中咱们能够看到,异步代码分割中,dist
目录中打包生成的文件是一个0.js
,这个0是Code Splitting
产生的一个id的值。
若是咱们想要将它改为咱们能够识别的名字,咱们就能够在上面异步代码的第一个参数前面添加/*webpackChunkName:"lodash"*/
,这个是在异步加载组件中存在的一个magic comment(语法注释)。
magic comment只能在官方动态加载组件的插件使用
//详细代码看异步代码中的index.js
return import(/*webpackChunkName:"lodash"*/'lodash').then(({default: _})
复制代码
打包后咱们能够看到vendors~lodash.js
,那么为何会在lodash
前面添加vendors
呢?这里咱们就须要去看咱们的配置了,官方文件中在optimization
中会有一个默认配置
splitChunks: {
chunks: "async",
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
priority: -20,
reuseExistingChunk: true
}
}
}
复制代码
其中:
更多详解参考官网split-chunks-plugin
aysnc
的意思是对异步代码进行分割,这就是为何在以前代码中异步代码分割不须要进行配置的缘由。vendors~lodash.js
。cacheGroup
里的名字有效。node_modules
中的时候,符合vendors
,就会在分割文件中添加前缀vendors
,当有多个node_modules
模块时候,就会将全部引用模块先进行缓存,最后的时候一块儿打包成vendors
文件。index.js
引入一个本身写的js文件,它就找到cacheGroup
,不符合vendors
的时候,就会进入default
中,这个时候打包文件的前缀就会有default
。default
中全部的模块都是符合的,当一个模块既符合vendors
又符合default
的时候,那么priority
的值越大,优先级越高。注:此文为本人学习过程当中的笔记记录,若是有错误或者不许确的地方请大佬多多指教~