利用webpack打包分析插件分析打包后的文件,发现chunk-vender中打包的有比较大的第三方组件echarts。为了减少首屏加载时间,我们可以从以下几个方面着手。
一、排除第三方库
我们可以把这些第三方的框架或者组件从chunk-vender中排除,以减小chunk-vender的体积,利用webpack的externals来把echarts从chunk-vender中排除,然后在index.html中把我们排除的内容通过cdn引入
chainWebpack: (config) => { config .plugin('webpack-bundle-analyzer') .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin) //忽略的打包文件 config.externals({ 'vue': 'Vue', 'vue-router': 'VueRouter', 'vuex': 'Vuex', 'axios': 'axios', 'echarts': 'echarts', 'moment': 'moment', 'element-ui': 'ELEMENT', }); },
二、组件懒加载
通过组件懒加载,来减小app.js的体积,需要注意的是每个组件webpackChunkName后面的名字不能相同,如果相同,就会打包进同一个同名文件中
{ path: '/connection/apply/test', name: '测试', meta: { i18n: '' }, component: () => import( /* webpackChunkName: "test" */ '@/views/connection/apply/test') },
三、压缩js、css,以及图片压缩
压缩功能webpack5+自带
// vue.config.js
const TerserJSPlugin = require('terser-webpack-plugin');
....
chainWebpack: (config) => {
// 开启js、css压缩
config.plugin('TerserJSPlugin')
.use(new TerserJSPlugin({
terserOptions: {
output: {
comments: false // 去掉注释
},
warnings: false,
compress: {
// eslint-disable-next-line camelcase
drop_console: true,
// eslint-disable-next-line camelcase
drop_debugger: true,
// pure_funcs: ['console.log'] // 移除console
}
}
}));
}
四、http缓存
可以和运维同学商讨http的缓存策略(1、强缓存2、协商缓存),如有需要请移步 http缓存详解
五、开启http压缩
# nginx前端静态资源配置
server {
listen 8080;
server_name _;
gzip_static on; // 开启gzip压缩
client_max_body_size 500m;
root /data/****/web/dist;
index index.html;
location ^~ /api {
proxy_pass http://***.**.**.***:8080/;
proxy_set_header Host ***.**.**.***;
}
}
六、拆解业务代码包
使用webpack的optimization,
// vue.config.js
....
chainWebpack: (config) => {
...
config.optimization && config.optimization.splitChunks({
// 拆包配置
chunks: 'all', //三选一:"initial" 初始化,"all"(默认就是all),"async"(动态加载)
minSize: 30000, // 形成一个新代码块最小的体积,只有 >= minSize 的bundle会被拆分出来 30000
maxSize: 0, //拆分之前最大的数值,默认为0,即不做限制
minChunks: 1, //引入次数,如果为2 那么一个资源最少被引用两次才可以被拆分出来
maxAsyncRequests: 5, // 按需加载的最大并行请求数
maxInitialRequests: 3, // 一个入口最大并行请求数
automaticNameDelimiter: '~', // 文件名的连接符
name: true,
cacheGroups: {
// node_modules模块包
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'chunk-vendors',
// name(module) {
// const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
// return `chunk.${packageName.replace('@', '')}`;
// },
chunks: 'all',
priority: -10,
},
// 共享模块
common: {
name: 'chunk-common',
minChunks: 2,
maxSize: 1024, //拆分之前最大的数值,默认为0,即不做限制
priority: -20,
reuseExistingChunk: true
}
}
});
...
}