社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
最近开发完一个vue项目,上线时发现首屏加载时间很长,通过分析首屏加载时浏览器加载的资源,发现是因为打包时,对node_modules文件夹下面的第三方依赖打包很集中,导致压缩的js很大,加载时间变长。
一开始路由就已经采用懒加载的方式,只不过没有采取懒加载分组的方式。懒加载分组模式如下:
{
path: 'Script',
name: 'Script',
component: () => import(/* webpackChunkName: "check-script" */'@/views/script/Script'),
meta: { title: '巡检脚本', roles: ['User'] }
},
{
path: 'AddScript',
name: 'AddScript',
component: () => import(/* webpackChunkName: "check-addscript" */'@/views/script/AddScript'),
meta: { title: '修改脚本', roles: ['User'] },
hidden: true
},
{
path: 'CheckObj',
name: 'CheckObj',
component: () => import(/* webpackChunkName: "check-obj" */'@/views/object/CheckObj'),
meta: { title: '巡检对象', roles: ['User'] }
},
注意:懒加载分组时,不宜将过多的组件分到同一个组,组尽量做到最小,这样在压缩打包时保证文件不过于庞大。打包之后,会根据分组名称,生成类似下面的压缩文件。
splitChunks
在vue.config.js中配置
const UglifyJsWebpackPlugin = require('uglifyjs-webpack-plugin')
chainWebpack(config) {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
// set preserveWhitespace
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.compilerOptions.preserveWhitespace = true
return options
})
.end()
config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === 'development',
config => config.devtool('cheap-source-map')
)
config
.when(process.env.NODE_ENV !== 'development',
config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime..*.js$/
}])
.end()
/** gzip 压缩 */
// config
// .plugin('compressionPlugin')
// .use(CompressionPlugin)
// .tap(() => [
// {
// test: /.js$|.html$|.css/, // 匹配文件名
// threshold: 10240, // 超过10k进行压缩
// deleteOriginalAssets: false, // 是否删除源文件
// minRatio: 0.8
// }
// ])
/** 去掉console.log debugger sourceMap*/
config.optimization.minimizer([
new UglifyJsWebpackPlugin({
/** 这个 sourceMap注释掉,默认就是置为false.(写为false 也是可以的)。
* 反之设为true 是生效的。
* 故在官方的配置(productionSourceMap: false)就可以注释掉了*/
sourceMap: false,
uglifyOptions: {
warnings: false,
compress: {
drop_console: true,
drop_debugger: true
}
}
})
])
config.optimization.splitChunks({
chunks: 'all',
minSize: 30000, // 字节 引入的文件大于30kb才进行分割
minChunks: 1, // 模块至少使用次数
maxAsyncRequests: 5, // 同时加载的模块数量最多是5个,只分割出同时引入的前5个文件
maxInitialRequests: 3, // 首页加载的时候引入的文件最多3个
automaticNameDelimiter: '~', // 缓存组和生成文件名称之间的连接符
name: true, // 缓存组里面的filename生效,覆盖默认命名
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\/]node_modules[\/]/,
priority: -10,
chunks: 'initial'
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: -5, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\/]node_modules[\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
avue: {
name: 'chunk-avue', // split elementUI into a single package
priority: -5, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\/]node_modules[\/]_?@smallwei(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 2, // minimum common number
priority: 10,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk({
name: 'manifest'
})
}
)
}
没有使用Gzip的原因是需要后台配合,目前的优化已经足够项目使用,如果以后项目迭代,引用的资源更加庞大的话,会尝试这个方法。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!