1.开启gzip压缩 compression-webpack-plugin
const CompressionPlugin = require('compression-webpack-plugin') // gzip压缩处理 chainWebpack: (config) => { if(isProd) { config.plugin('compression-webpack-plugin') .use(new CompressionPlugin({ test: /\.js$|\.html$|\.css$/, // 匹配文件名 threshold: 10240, // 对超过10k的数据压缩 deleteOriginalAssets: false // 不删除源文件 })) } }
Gzip压缩是一种强力压缩手段,针对文本文件时通常能减少2/3的体积。
HTTP协议中用头部字段Accept-Encoding
和 Content-Encoding
对「采用何种编码格式传输正文」进行了协定,请求头的Accept-Encoding
会列出客户端支持的编码格式。当响应头的 Content-Encoding
指定了gzip时,浏览器则会进行对应解压
一般浏览器都支持gzip,所以Accept-Encoding
也会自动带上gzip
,所以我们需要让资源服务器在Content-Encoding
指定gzip,并返回gzip文件
Nginx配置Gzip
#开启和关闭gzip模式 gzip on; #gizp压缩起点,文件大于1k才进行压缩 gzip_min_length 1k; # gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间 gzip_comp_level 6; # 进行压缩的文件类型。 gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript ; # nginx对于静态文件的处理模块,开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩 gzip_static on # 是否在http header中添加Vary: Accept-Encoding,建议开启 gzip_vary on; # 设置gzip压缩针对的HTTP协议版本 gzip_http_version 1.1;
2.Webpack Bundle分析
3.优化分包策略
optimization: isProd ? { splitChunks: { chunks: 'all', maxInitialRequests: Infinity, // 默认为3,调整为允许无限入口资源 minSize: 20000, // 20K以下的依赖不做拆分 cacheGroups: { vendors: { // 拆分依赖,避免单文件过大拖慢页面展示 // 得益于HTTP2多路复用,不用太担心资源请求太多的问题 name(module) { // 拆包 const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1] // 进一步将Ant组件拆分出来,请根据情况来 // const packageName = module.context.match(/[\\/]node_modules[\\/](?:ant-design-vue[\\/]es[\\/])?(.*?)([\\/]|$)/)[1] return `npm.${packageName.replace('@', '')}` // 部分服务器不允许URL带@ }, test: /[\\/]node_modules[\\/]/, priority: -10, chunks: 'initial' } } }, runtimeChunk: { name: entrypoint => `runtime-${entrypoint.name}` } } : {}
vue inspect > output.js --mode production 可以查看最终配置
4.构建时压缩图片 image-webpack-loader
chainWebpack: (config) => { if (isProd) { // 图片压缩处理 const imgRule = config.module.rule('images') imgRule .test(/\.(png|jpe?g|gif|webp)(\?.*)?$/) .use('image-webpack-loader') .loader('image-webpack-loader') .options({ bypassOnDebug: true }) .end() } }
注意:install或build时如果出现imagemin库下载失败,可以尝试 换源、配置github hosts、install时添加--user=root
解决
5.优化svg图标 svg-sprite-loader
chainWebpack: (config) => { // SVG处理 config.module .rule('svg') .exclude.add(resolve('src/icons/svg')) .end() config.module .rule('icons') .test(/\.svg$/) .include.add(resolve('src/icons/svg')) .end() .use('svg-sprite-loader') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]' }) .end() }
6.moment按需加载
7.echart按需加载
7.优化Ant-design-vue体积
。。。
optimization: isProd ? {
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity, // 默认为3,调整为允许无限入口资源
minSize: 20000, // 20K以下的依赖不做拆分
cacheGroups: {
vendors: {
// 拆分依赖,避免单文件过大拖慢页面展示
// 得益于HTTP2多路复用,不用太担心资源请求太多的问题
name(module) {
// 拆包
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
// 进一步将Ant组件拆分出来,请根据情况来
// const packageName = module.context.match(/[\\/]node_modules[\\/](?:ant-design-vue[\\/]es[\\/])?(.*?)([\\/]|$)/)[1]
return `npm.${packageName.replace('@', '')}` // 部分服务器不允许URL带@
},
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'initial'
}
}
},
runtimeChunk: { name: entrypoint => `runtime-${entrypoint.name}` }
} : {}