前言
这几天发现我负责的项目很卡,就简单记录一下,用的是vuecli3和webpack5
打包分析
首先我们要通过两个插件来分析一下打包时间以及大小
如果是vuecli2的话,参考这里:www.cnblogs.com/zhurong/p/1…
-
webpack-bundle-analyzer
//vue.config.js
chainWebpack: config => {
config
.plugin("webpack-bundle-analyzer")
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
.end();
}
//package.json
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"report": "npm_config_report=true npm run build",
}
npm run build --report 便可以查看打包之后的文件大小
-
speed-measure-webpack-plugin
//vue.config.js
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
module.exports = {
configureWebpack() {
return smp.wrap({
plugins:[]
})
}
打包之后就可以查看
构建优化
-
HappyPack多线程
const HappyPack = require('happypack');
const os = require("os");
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
module.exports = {
config.plugin('happypack')
.use(HappyPack)
.tap(options => {
options[0] = {
id: 'babel',
loaders: ['babel-loader?cacheDirectory=true'], //开启缓存
threadPool: happyThreadPool
}
return options
})
const hRule = config.module.rule('js')
hRule.test(/\.js$/)
.include.add(resolve('src'))
.end()
hRule.uses.clear()
hRule.use('happypack/loader?id=babel')
.loader('happypack/loader?id=babel')
.end();
}
首屏渲染优化
-
基础处理
-
代码模块化
- 封装可复用代码
- 代码压缩工具:tool.oschina.net/jscompress
-
图片
- 懒加载
- 图标:SVG在既能满足现有图片的功能的前提下,又是矢量图。在可访问性上面也非常不错,并且有利于SEO和无障碍,在性能和维护性方面也比icon font要出色许多,同时也可以使用 svg-sprite-loader 将svg图片拼接成sprite图
其实大多数情况下字体图标就已经够了,如果非要压榨的话,那不妨试试使用SVG,当然兼容性也是问题,有兴趣可以看一下这篇文章。
- 本地图片:
TinyPNG工具:tinypng.com/ (有损压缩的同时,尽可能的保持清晰度,好像npm 也有这样的插件)
url-loader 小于5KB的小图片转换base64,减少请求
chainWebpack (config) {
const imagesRule = config.module.rule("images")
imagesRule
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options, { limit: 5120 }))
}
image-webpack-loader (有可能因为外网下载不完全导致报错,推荐使用cnpm安装)
//vue.config.js配置
chainWebpack(config){
config.module
.rule("images")
.use("image-webpack-loader")
.loader("image-webpack-loader")
.options({
bypassOnDebug: true
})
.end();
}
-
按需加载
- 路由懒加载 平常用就两种
1、es的import
{
name:"login",
path: "/login",
component: () => import("@/views/login/index") //import会返回一个Promise对象
}
2、require
{
name:"login",
path:"login",
component:resolve = > require(["@/views/login/index"],resolve),
}
- 组件尽量避免组件全局挂载
-
第三方库CDN引入,减少打包体积
例如echart、ElementUI这种很大的第三库通过CDN引入,既能减小app.js体积,也能减轻服务器压力
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/4.8.0/echarts.min.js"></script>
module.export = (config)=>{
chainWebpack(config){
config.externals({
'echarts': 'echarts'
});
}
}
-
GZIP压缩
modUle.export = (config)=>{
chainWebpack()
chainWebpack(config){
.plugin("compression")
.use("compression-webpack-plugin", [
{
filename: "[path].gz[query]",
algorithm: "gzip",
test: new RegExp(
"\\.(" + productionGzipExtensions.join("|") + ")$"
),
threshold: 8192,
minRatio: 0.8,
},
])
.end();
}
}
后端Nginx配置
//来源:https://blog.csdn.net/zSY_snake/article/details/108062483
#开启和关闭gzip模式
gzip on|off;
#gizp压缩起点,文件大于1k才进行压缩
gzip_min_length 1k;
# gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间
gzip_comp_level 5;
# 进行压缩的文件类型。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript ;
#nginx对于静态文件的处理模块,开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩
gzip_static on|off
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 设置压缩所需要的缓冲区大小,以4k为单位,如果文件为7k则申请2*4k的缓冲区
gzip_buffers 2 4k;
# 设置gzip压缩针对的HTTP协议版本
gzip_http_version 1.1;
看见返回头有 Content-Encoding:gzip 就表示成功!