- 使用
webpack
生成包文件分析,找出问题根源 - gzip 压缩
- 减少http请求
- 图片/路由懒加载
- cdn 解除浏览器同源请求数量限制
- UI 框架按需加载
- 压缩字体文件(字蛛)
- vue-cli 减少全局引用的组件
CDN
public/index.html
新增
<% for(var css of htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%=css%>" as="style" />
<% } %> <% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%=js%>"></script>
<% } %>
<!DOCTYPE html>
<html>
<body>
<div id="app"></div>
<!-- _____找到这个位置复制在下边______ -->
<% for(var css of htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%=css%>" as="style" />
<% } %> <% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%=js%>"></script>
<% } %>
</body>
</html>
vue.config.js
chainWebpack: (config) => {
const cdn = {
css: [],
js: [
'https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.min.js',
'https://cdn.bootcdn.net/ajax/libs/vue-router/3.1.3/vue-router.min.js',
'https://cdn.bootcdn.net/ajax/libs/vuex/3.1.2/vuex.min.js',
'https://cdn.bootcdn.net/ajax/libs/axios/0.18.0/axios.min.js'
],
};
config.externals({
vue: 'Vue',
// 'element-ui': 'ELEMENT',
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: 'axios',
});
// 通过 html-webpack-plugin 将 cdn 注入到 index.html 之中
config.plugin('html').tap((args) => {
args[0].cdn = cdn;
return args;
});
}
如果需要开发时候用 npm 本地的包,生产环境用 cdn 的话,需要在 index.html
和 vue.config.js
加一层判断process.env.NODE_ENV===production
html
<% if(process.env.NODE_ENV === 'production') { %>
<% for(var css of htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%=css%>" as="style" />
<% } %>
<% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%=js%>"></script>
<% } %>
<% } %>
vue.config.js
chainWebpack: (config) => {
if(process.env.NODE_ENV === 'production') {
... gzip 配置
}
}
gzip
前端部分
// npm i compression-webpack-plugin -D
const CompressionWebpackPlugin = require('compression-webpack-plugin');
// module.exports.configureWebpack
configureWebpack: (config) => {
config.plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /\.(html|js|css|ttf)$/,
threshold: 10240, // min-size 10KB
minRatio: 0.8, // 压缩率小于值 才会被处理
deleteOriginalAssets: false, // 删除原文件
})
);
// config.plugins.push(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)); // 不知道是什么
}
如果你设置了 configureWebpack 对象形式的路径别名,则需要合并一下
configureWebpack: {
resolve: {
alias: {
CSS: resolve('src/assets/css'),
IMG: resolve('src/assets/images'),
JS: resolve('src/assets/js'),
},
},
plugins: [
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /\.(html|js|css|ttf)$/,
threshold: 10240, // min-size 10KB
minRatio: 0.8, // 压缩率小于值 才会被处理
deleteOriginalAssets: false, // 删除原文件
}),
],
},
当然也可以 以 configureWebpack 函数形式配置路径别名
configureWebpack: config => {
config.resolve.alias
.set('@', resolve('src'))
.set('IMG', resolve('src/assets/image'))
}
nginx 需要对应开启 gzip 和静态 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/xml text/javascript application/json image/png image/gif image/jpeg;
#nginx对于静态文件的处理模块,开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩
# gzip_static on|off
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 设置压缩所需要的缓冲区大小,以4k为单位,如果文件为7k则申请2*4k的缓冲区
gzip_buffers 4 16k;
# 设置gzip压缩针对的HTTP协议版本
# gzip_http_version 1.1;
server {
gzip on;
gzip_static on;
}
路由懒加载
设置路由懒加载后,进入首屏会发现还是预加载了所有路由文件,如果不想预加载需要手动设置
但是这个说不太会影响首屏加载事件,而且会加快页面跳转的速度
chainWebpack: (config) => {
config.plugins.delete('prefetch');
}
减少全局组件
vue 日常开发中,经常注册全局组件方便使用
如果全局组件是自己写的还好,如果一个全局组件 Table.vue 中是对 el-table 进行的二次封装,则首屏加载的时候会看到一个巨大的 js 文件 chunk-vendors.js -> 4.5M
所以尽量减少 全局组件的可能,不然的话只是单纯的跳 /login 页面都可能卡 3s 白屏
相关博客
https://juejin.im/post/6859927704037572621
https://www.jianshu.com/u/0427dce733d3
https://segmentfault.com/a/1190000019499007
https://www.cnblogs.com/zs-note/p/9556390.html
https://mp.weixin.qq.com/s/gBnTbl3V8-Wx3YT6_-8dBQ