减少代码体积
Tree Shaking
又称为摇树,它只能的减少引入的代码,以下的几种情况都会被摇树所剔除。
- 你引入了代码,但是没有使用
- 你映入的库中的方法
以上的代码都会被剔除
在webpack中默认开启了这个选项
必要依赖es module
babel处理
babel会自动的产生一些runtime
代码,以达到代码复用的问题,默认会在每个模块中都生成这么份代码。
可以使用@babel/plugin-transform-runtime
这个插件来单独的生成runtime
代码 可以减少体积
使用方法
sh
yarn add -D @babel/plugin-transform-runtime
1
javascript
module.exports = {
module: {
rules: [{
oneOf: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true, // 打开Babel缓存
cacheCompression: false, //关闭缓存的压缩
plugins: ["@babel/plugin-transform-runtime"]
}
},
}
]
}]
},
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
image minimizer
可以压缩图片来达到减少体积的效果
- 下载包
无损压缩
sh
yarn add -D image-minimizer-webpack-plugin imagemin imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo
1
有损压缩
sh
yarn add -D image-minimizer-plugin imagemin imagemin-gifsicle imagemin-mozjepg imagemin-pngquant imagemin-svgo
1
code split
TIP
code split
是指对代码进行分割,默认的情况下,webpack会将所有的代码都打包在一个文件中,这个文件的体积就会很大,但实际上比如在首页中,我们并不需要其他页面的代码,一个页面只加载自己页面的js代码就变的尤为重要,这会显著的提升我们加载的速度。
第一张方案:多文件入口
在配置属性的entry中,如果我们配置一个对象的话,webpack就会以多文件的方式进行打包
js
module.exports = {
entry: {
index: "./src/index.js",
app: './src/app.js'
},
output: {
filename: '[name].js', // filename以中括号的形式
path: resolve(__dirname, '../build/static/'),
clean: true
},
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
公共代码复用
一些公共函数,在多入口文件中可能都会用到,我们可以将这部分进行抽离。
js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
default: {
minSize: 0, // 当文件大小> 多少时进行抽离 默认是20kb
minChunks: 2, // 最小的被引入数,也就是至少要被两个以上的文件引入才会单独分离
priority: 20, // 权重
reuseExistingChunk: true
}
}
}
},
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
动态导入
动态导入是指,页面再初始化的时候,有些代码看您不需要用到,只有发生某些操作的时候,再将这些代码进行导入
TIP
在webpack中,如果import
是以函数的形式进行加载的,那么webpack会将这部分的代码单独进行抽离
javascript
const button = document.querySelector('.button')
button.addEventListener('click', async () => {
const { count } = await import('./count')
count()
})
1
2
3
4
5
2
3
4
5
为单独抽离的包命名
经过上面的试验,我们会发现,单独打包出来的js会取一些比较随意的名字,比如这样
我们可以使用webpack中的魔术关键字,来命名这些模块,使其有更好的语义化
javascript
const button = document.querySelector('.button')
button.addEventListener('click', async () => {
const { count } = await import(/* webpackChunkName:"count" */ './count')
count()
})
1
2
3
4
5
2
3
4
5
preload / prefetch
preload
: 告诉浏览器立即加载资源prefetch
: 告诉浏览器空闲的时候加载资源
共同特点
- 只加载,不执行。
- 都有缓存 区别
- preload加载优先级高于prefetch
- preload只会加载当前页面可使用的资源,prefetch可以加在下个页面使用的资源
- preload会比prefetch兼容性更好
实现这个功能需要使用@vue/preload-webpack-plugin
这个插件,这是vue社区做的一个插件
sh
yarn add @vue/preload-webpack-plugin -D
1
js
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin')
module.exports = {
plugins:[
new PreloadWebpackPlugin({
rel: 'preload', // 可以改为 prefetch
as: 'script'
})
]
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
PWA
PWA
是指当项目处于网络离线时,提供项目离线体验,使浏览器在断网的情况下依然能狗访问
sh
yarn add workbox-webpack-plugin --D
1
js
const WorkboxPlugin = require('workbox-webpack-plugin');
module.exports = {
plugins: [
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true,
}),
],
};
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
在入口文件中添加此段代码
js
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js').then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9