vue2首屏加载20s+到2s的优化过程

255 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

优化背景

前端项目部署到服务器,首屏加载速度过于缓慢,白屏时间过长用户体验极度不好,用户严重流失

2.png 1.png

问题分析&&解决办法

为什么会出现这样的问题?该怎么解决(避免)?
打包文件过大,线上请求时间过长(服务器带宽也有影响),问题已知晓,开始从以下几方面优化:

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加载静态资源

1669968512539_8EF75058-B966-4a01-8CB6-7E6C9692DC7E.png

通过上面的优化项目已经可以控制在五秒之内了,当然也不排除项目很大,加载时间仍很长这时候就需要终极大招了

效果图:

1.png 服务器解析的时候优先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>
效果图

1.png

7.预加载(这个我没用到,嘻嘻嘻)

经过上边一系列成功把20s+的加载成功时间缩短为2s 大功告成