开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
优化背景
前端项目部署到服务器,首屏加载速度过于缓慢,白屏时间过长用户体验极度不好,用户严重流失
问题分析&&解决办法
为什么会出现这样的问题?该怎么解决(避免)?
打包文件过大,线上请求时间过长(服务器带宽也有影响),问题已知晓,开始从以下几方面优化:
1.防止编译文件中出现map文件
在 vue.config.js 文件中将productionSourceMap的值设置为false
2.路由采用懒加载
`{
path: 'user',
component: resolve => require(['@/views/system/user'],resolve),
name: 'user',
meta: { title: '用户管理'}
}`
3.生产环境依赖包采用cdn方式引入
vue.config.js配置如下
// 是否为生产环境
const isProduction = process.env.NODE_ENV === "production";
// 本地环境是否需要使用cdn
const devNeedCdn = false;
const cdn = {
// cdn:模块名称和模块作用域命名
externals: {
vue: "Vue",
vuex: "Vuex",
"vue-router": "VueRouter",
axios: "axios",
ElementUI: "element-ui",
},
// cdn的elementui css链接
css: ["https://cdn.bootcss.com/element-ui/2.15.6/theme-chalk/index.css"],
// cdn的js链接
js: [
"https://cdn.bootcss.com/vue/2.6.10/vue.min.js",
"https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js",
"https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js",
"https://cdn.bootcss.com/axios/0.18.1/axios.min.js",
"https://cdn.bootcss.com/element-ui/2.15.6/index.js",
]
};
chainWebpack(config) {
// ============注入cdn start============
if (isProduction) {
config.plugin("html").tap((args) => {
// 生产环境或本地需要cdn时,才注入cdn
if (isProduction || devNeedCdn) args[0].cdn = cdn;
return args;
});
config.externals(cdn.externals);
}
}
index.html配置如下
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow" rel="stylesheet" />
<% } %>
<!-- 使用CDN的JS文件 -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
4.开启gzip打包
const isProduction = process.env.NODE_ENV === "production";
// 打包 使用gzip压缩
const CompressionWebpackPlugin = require('compression-webpack-plugin');
// 定义压缩文件类型
const productionGzipExtensions = ['js', 'css'];
if (isProduction) {
//gzip压缩
cdn.CompressionWebpackPlugin.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'), // 匹配文件名
threshold: 10240, // 对超过10K的数据进行压缩
minRatio: 0.8, // 极小比
})
)
}
服务器nginx配置gzip加载静态资源
通过上面的优化项目已经可以控制在五秒之内了,当然也不排除项目很大,加载时间仍很长这时候就需要终极大招了
效果图:
服务器解析的时候优先gzip压缩包,减少请求时间,当然有的浏览器不支持gzip 会请求源文件
5.异步组件
子组件
<template>
<div class="asyncCmp">
一个不需要在首屏中加载的组件。
</div>
</template>
父组件
<template>
<div id="app">
<AsyncCmp />
</div>
</template>
<script>
import AsyncCmp from './components/async-cmp'
export default {
components: {
AsyncCmp,
}
}
</script>
6.使用骨架屏/加载过度动画
在index.html 写loading动画过度,防止白屏 ` .loading-content { width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; }
.loading {
display: inline-block;
font-size: 28px;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
color: #fff;
text-shadow: 0 0 2px #1890ff, 0 0 1px #1890ff, 0 0 1px #1890ff;
letter-spacing: 2px;
position: relative;
}
.loading::after {
content: "Loading";
position: absolute;
left: 0;
top: 0;
color: #1890ff;
width: 0%;
height: 100%;
overflow: hidden;
animation: loading-animation 3s linear infinite;
}
@keyframes loading-animation {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
</style>`
<div id="app">
<div class="loading-content">
<div class="loading">Loading</div>
</div>
</div>