最近从零开始配置了一个pc端项目,感觉本地服务启动很慢,还没写什么代码,就需要启动2s~3s,有点不可思议。
对比之前写H5项目时感觉启动速度快很多。于是决定优化一下。
怎么优化呢,先从分包开始吧。
目前启动慢,很大原因是所有代码和样式都被打包到同一个输出文件,导致这个文件非常大,应该是很多兆。所以最后上传、下载、加载的速度都很慢。
js分包加载
1. 修改输出文件名
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
改成:
output: {
filename: '[name].js',
chunkFilename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
2. 添加optimization配置
optimization: {
runtimeChunk: 'single', //会将Webpack在浏览器端运行时需要的代码单独抽离到一个文件
splitChunks: {
cacheGroups: {
commons: {
//产生一个Chunk
chunks: 'initial',
minChunks: 2,
maxInitialRequests: 5, // The default limit is too small to showcase the effect
minSize: 0 // This is example is too small to create commons chunks
},
vendor: {
//产生一个Chunk
test: /node_modules/,
chunks: 'initial',
name: 'vendor',
priority: 10,
enforce: true
}
}
}
}
总共会生成三个文件:main.js,runtime.js,vendor.js
这样以来,由原来的main.js
分离出来三个js文件,不仅提升的加载速度,也提升了代码可读性,业务代码主要集中在runtime.js文件里。
3. webpack全量配置:
module.exports = {
entry: './src/index.jsx', //入口,相对路径
output: {
// filename: 'main.js', //打包后的文件名
filename: '[name].js', //打包后输出文件的文件名
chunkFilename: '[name].js',
path: path.resolve(__dirname, 'dist') //打包后的路径(文件夹路径),必须是绝对路径,"__dirname"指当前路径
},
//生成多个js文件
optimization: {
runtimeChunk: 'single', //会将Webpack在浏览器端运行时需要的代码单独抽离到一个文件
splitChunks: {
cacheGroups: {
commons: {
//产生一个Chunk
chunks: 'initial',
minChunks: 2,
maxInitialRequests: 5, // The default limit is too small to showcase the effect
minSize: 0 // This is example is too small to create commons chunks
},
vendor: {
//产生一个Chunk
test: /node_modules/,
chunks: 'initial',
name: 'vendor',
priority: 10,
enforce: true
}
}
}
},
}
css分包加载(抽离css文件)
上面抽离出多个js文件,如果想抽离css文件,该怎么做?
网上大多数教程,包括webpack官网给出的都是用mini-css-extract-plugin
插件进行抽离。
方法没错,但是根据webpack版本不同,配置有所区别。
1. webpack5以下版本配置
webpack5以下版本,用下面这种方式加载应该没有问题:
let MiniCssExtractPlugin = require('mini-css-extract-plugin') //css单独分离文件加载
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css', //抽离css之后输出的文件名
chunkFilename: '[id].css'
})
],
module: {
//模块
rules: [
{
test: /\.css$/, //匹配到css结尾的文件,加载css-loader,
use: [
{
'style-loader',
MiniCssExtractPlugin.loader,
'css-loader'
]
},
{
test: /\.less$/, //匹配到less结尾的文件
use: [
'style-loader',
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader'
]
}
]
}
}
注意 MiniCssExtractPlugin.loader
需要放在'style-loader'和'css-loader'之间
2. webpack5以上版本配置
webpack5以上版本,需要在MiniCssExtractPlugin.loader
配置里添加一个esModule: false
属性。
use: [
'style-loader',
{
loader: MiniCssExtractPlugin.loader,
options: {
esModule: false,
},
},
'css-loader',
'sass-loader'
]
完整webpack配置如下:
const path = require('path')
let MiniCssExtractPlugin = require('mini-css-extract-plugin') //css单独分离文件加载
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css', //抽离css之后输出的文件名
chunkFilename: '[id].css'
})
],
module: {
//模块
rules: [
{
test: /\.css$/, //匹配到css结尾的文件,加载css-loader,
use: [
{
loader: 'style-loader',
options: {
//将当前loader添加到<head>标签内容的最上面
insert: function (element) {
var parent = document.querySelector('head')
var lastInsertedElement =
window._lastElementInsertedByStyleLoader
if (!lastInsertedElement) {
parent.insertBefore(element, parent.firstChild)
} else if (lastInsertedElement.nextSibling) {
parent.insertBefore(element, lastInsertedElement.nextSibling)
} else {
parent.appendChild(element)
}
}
}
},
{
//css单独分离文件加载
loader: MiniCssExtractPlugin.loader,
options: {
esModule: false
}
},
'css-loader'
]
},
{
test: /\.less$/, //匹配到less结尾的文件
use: [
{
loader: 'style-loader',
options: {
//将当前loader添加到<head>标签内容的最上面
insert: function (element) {
var parent = document.querySelector('head')
var lastInsertedElement =
window._lastElementInsertedByStyleLoader
if (!lastInsertedElement) {
parent.insertBefore(element, parent.firstChild)
} else if (lastInsertedElement.nextSibling) {
parent.insertBefore(element, lastInsertedElement.nextSibling)
} else {
parent.appendChild(element)
}
}
}
},
{
//css单独分离文件加载
loader: MiniCssExtractPlugin.loader,
options: {
esModule: false
}
},
'css-loader',
'less-loader'
]
}
]
}
}
运行结果发现多了两个css文件:main.css,vendor.css
main.css 里面主要是我们自己写的css的集合。
vendor.css一般都是第三方组件的样式集合。
暂无评论