vue项目,首页加载过慢,白屏时间太长

1,453 阅读2分钟

vue项目,首页加载过慢,白屏时间太长

问题

  1. 清除浏览器缓存
  2. 打开首页
  3. app.js 跟 chunk-vendors.js 超过过大,请求状态200,但是时间太长

解决 1.压缩

安装命令: yarn add compression-webpack-plugin@5.0.1

注意:如果你这里直接不加@5.0.1版本进行安装,有可能编译的时候会出现异常:Cannot read property 'tapPromise' of undefined 原因是webpack的包版本不兼容

// vue.config.js
const path = require('path');
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
configureWebpack: (config) => {
  // 代码 gzip
  const productionGzipExtensions = ['html', 'js', 'css'];
  config.plugins.push(
    new CompressionWebpackPlugin({
      filename: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
      threshold: 10240, // 只有大小大于该值的资源会被处理 10240
      minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
      deleteOriginalAssets: false, // 删除原文件
    })
  );
},

同时需要配置nginx才可支持gzip(前端借助宝塔部署,发现宝塔中nginx的配置已经添加了gzip的配置)

// nginx.conf
http {
  #nginx开启gzip
  #前端文件在build的时候已经配置好压缩,需要再配置一下nginx;
  gzip on; 
  gzip_static on;
  gzip_buffers 4 16k;
  gzip_comp_level 5;
  gzip_types text/plain application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg 
              image/gif image/png;   
}

2.模块细分

splitChunks: {
  chunks: 'all', // 不管文件是动态还是非动态载入,统一将文件分离。当页面首次载入会引入所有的包
  maxInitialRequests: 10, // 最大初始化请求数
  minSize: 0, // 默认30000,为了不合并 chunk
  cacheGroups: {
    vendor: {
      test: /[\/]node_modules[\/]/,
      name(module) {
        const packageName = module.context.match(
          /[\/]node_modules[\/](.*?)([\/]|$)/,
        )[1];
        return `npm.${packageName.replace('@', '')}`; // 提取各个第三方组件,只在需要时提取
      },
    },
  },
},

3.cdn引入

vue.config.js中配置不打包相关资源. 这样可以大幅降低项目打包文件大小

// vue.config.js
const cdn = {
  css: [
    // antd css 由于引入失败只好放弃了antd的按需引入
  ],
  js: [
    // vue
    'https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.min.js',
    // vue-router
    'https://cdn.bootcdn.net/ajax/libs/vue-router/3.1.3/vue-router.min.js',
    // vuex
    'https://cdn.bootcdn.net/ajax/libs/vuex/3.1.2/vuex.min.js',
    // axios
    'https://cdn.bootcdn.net/ajax/libs/axios/0.18.0/axios.min.js',
    // moment
    'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js',
  ],
};

chainWebpack: (config) => {
  // 正式环境配置cdn引入
  if (process.env.NODE_ENV === 'production') {
    let externals = {
      vue: 'Vue',
      axios: 'axios',
      'vue-router': 'VueRouter',
      vuex: 'Vuex',
      moment: 'moment',
    };
    config.externals(externals);
    // 通过 html-webpack-plugin 将 cdn 注入到 index.html 之中
    config.plugin('html').tap((args) => {
      args[0].cdn = cdn;
      return args;
    });
  }
},

然后在public/index.html中加入以下代码, 正式环境才走cdn

<% 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>
<% } %>
<% } %>

4路由懒加载

这样能让打包出来的代码分割, 而不会统统堆一个文件里. 这样的好处是首屏渲染在用户眼里更快了.

// router.js
const routes: Array<RouteConfig> = [
  {
    path: '/',
    name: 'Chat',
    component: () => import('@/views/GenalChat.vue'),
  },
];

参考链接:juejin.cn/post/685992…

shuliqi.github.io/2021/06/21/…

www.cnblogs.com/ingstyle/p/…

blog.towavephone.com/webpack-upg…

m.zyiz.net/tech/detail…

webpack性能分析插件

使用webpack-bundle-analyzer 进行体积分析。该插件可生成依赖包形成可视化分析图谱,帮组开发者分析项目结构

image.png 按照图片中配置,执行npm run build --report,打包成功后访问http://localhost:8888/

image.png 通过分析哪些资源过大,进一步解决首页加载过慢问题。

如果webpack-bundle-analyzer不能正常使用,则使用npm导入后再使用。