解决 Vue 打包 chunk-vendors.js 文件过大导致页面加载缓慢的问题

1、下载 compression-webpack-plugin 插件:

npm install --save-dev compression-webpack-plugin
// 由于安装最新版本会安装失败,报错 unable to resolve dependency tree
// 所以需要找一个低版本的进行安装,如果不知道安装什么版本合适,就直接去 npm 官网找到这个组件,找到发布版本列表,一个一个的从新到旧安装,直到成功为止!
// 上面的如果安装失败就先用这个版本,或按照上句话所说的去尽量安装新的版本
npm install --save-dev compression-webpack-plugin@6.1.1

2、修改 vue.config.js:

const CompressionWebpackPlugin = require("compression-webpack-plugin");

module.exports = {
  ... ...
  // 自定义webpack配置
  configureWebpack: (config) => {
    config.plugins.push(
      new CompressionWebpackPlugin({
        algorithm: "gzip",
        test: /\.js$|\.html$|\.json$|\.css/,
        threshold: 10240,
        minRatio: 0.8
      })
    );
    // 开启分离js
    config.optimization = {
      runtimeChunk: "single",
      splitChunks: {
        chunks: "all",
        maxInitialRequests: Infinity,
        minSize: 20000,
        cacheGroups: {
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name(module) {
              // get the name. E.g. node_modules/packageName/not/this/part.js
              // or node_modules/packageName
              const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
              // npm package names are URL-safe, but some servers don't like @ symbols
              return `npm.${packageName.replace("@", "")}`;
            }
          }
        }
      }
    };
    // 取消webpack警告的性能提示
    config.performance = {
      hints: "warning",
      //入口起点的最大体积
      maxEntrypointSize: 50000000,
      //生成文件的最大体积
      maxAssetSize: 30000000,
      //只给出 js 文件的性能提示
      assetFilter: function(assetFilename) {
        return assetFilename.endsWith(".js");
      }
    };
    config.plugins.forEach((val) => {// 使用 CDN 链接引入时加上
      if (val instanceof HtmlWebpackPlugin) {
        val.options.cdn = cdn;
      }
    });
    return {
      externals, // 使用 CDN 链接引入时加上,打包时忽略这些依赖
      resolve: {
        alias: {
          "@": resolve("src")
        }
      },
      output: {
        // 把子应用打包成 umd 库格式
        library: `${name}-[name]`,
        libraryTarget: "umd",
        jsonpFunction: `webpackJsonp_${name}`
      }
    };
  },
  ... ...
};

3、后端 nginx 配置:

server {
    listen       80;
    server_name  localhost;
    location / {
        try_files $uri $uri/ /index.html;
        root C:/nginx-1.18.0/html/gzip/dist;
        index  index.html index.htm;
    }
    location /api/ {
        proxy_pass http://localhost:6666/;
    }
    
    # 主要是下方的gizp配置
    gzip on; # 开启gzip压缩
    gzip_min_length 4k; # 小于4k的文件不会被压缩,大于4k的文件才会去压缩
    gzip_buffers 16 8k; # 处理请求压缩的缓冲区数量和大小,比如8k为单位申请16倍内存空间;使用默认即可,不用修改
    gzip_http_version 1.1; # 早期版本http不支持,指定默认兼容,不用修改
    gzip_comp_level 2; # gzip 压缩级别,1-9,理论上数字越大压缩的越好,也越占用CPU时间。实际上超过2的再压缩,只能压缩一点点了,但是cpu确是有点浪费。因为2就够用了
                # 压缩的文件类型 MIME类型,百度一下,一大把                                    # css             # xml             # 识别php     # 图片
    gzip_types text/plain application/x-javascript application/javascript text/javascript text/css application/xml application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/x-woff font/ttf;
                # text                   # 早期js                 # js        # js的另一种写法                                                                                 # .eot字体                   # woff字体  # ttf字体
    gzip_vary on; # 是否在http header中添加Vary: Accept-Encoding,一般情况下建议开启       
}

4、路由懒加载:

import Vue from "vue";
import Router from "vue-router";
import Login from "components/login";

Vue.use(Router);

const router = new Router({
  routes: [
    {
      path: "/",
      name: "Login",
      component: Login
    },
  ]
});

export default router;

// 改成下面这种

import Vue from "vue";
import Router from "vue-router";

Vue.use(Router);

const router = new Router({
  routes: [
    {
      path: "/",
      name: "Login",
      component: () => import("components/login")
    },
  ]
});

export default router;

### 优化 chunk-vendors.js 文件导致首页加载白屏的问题 #### 分析问题Vue3 或 Vue CLI 构建的项目中,`chunk-vendors.js` 是 Webpack 打包生成的一个包含所有依赖库(如 VueVue Router、Vuex 等)的文件。当该文件体积较时,会显著拖慢页面的首次加载速度,导致用户看到长时间的白屏现象。 #### 优化方案 ##### 1. 使用 `externals` 配置,通过 CDN 引入第三方库 通过将常用的型库(如 Vue、Element UI、ECharts 等)从打包过程中排除,并通过 CDN 引入,可以有效减小 `chunk-vendors.js` 的体积。 在 `vue.config.js` 中配置如下: ```javascript module.exports = { configureWebpack: (config) => { return { externals: { vue: 'Vue', 'element-plus': 'ElementPlus', axios: 'axios', dayjs: 'dayjs', }, }; }, }; ``` 同时,在 `index.html` 文件中引入对应的 CDN 资源: ```html <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> <script src="https://unpkg.com/element-plus"></script> <link href="https://unpkg.com/element-plus/dist/index.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/dayjs/dayjs.min.js"></script> ``` ##### 2. 启用 Gzip 压缩 Gzip 可以幅减少静态资源文件小,提升网络传输效率。 在 `vue.config.js` 中启用 `CompressionPlugin` 插件: ```javascript const CompressionPlugin = require('compression-webpack-plugin'); module.exports = { configureWebpack: (config) => { return { plugins: [ new CompressionPlugin({ algorithm: 'gzip', test: /\.js$|\.css$|\.html$/, filename: '[path].gz[query]', minRatio: 0.8, threshold: 10240, deleteOriginalAssets: false, }), ], }; }, }; ``` ##### 3. 拆分 `chunk-vendors.js` 文件 通过 Webpack 的代码分割功能,可以将 `chunk-vendors.js` 拆分为多个较小的文件,充分利用浏览器的多线程下载能力。 在 `vue.config.js` 中配置: ```javascript module.exports = { chainWebpack: (config) => { config.optimization.splitChunks({ cacheGroups: { vendors: { name: 'chunk-vendors', chunks: 'initial', minChunks: 2, maxInitialRequests: 5, minSize: 0, priority: 1, reuseExistingChunk: true, enforce: true, }, common: { name: 'chunk-common', chunks: 'initial', minChunks: 2, maxInitialRequests: 5, minSize: 0, priority: 1, reuseExistingChunk: true, enforce: true, }, }, }); }, }; ``` ##### 4. 添加首屏 Loading 动画 为了改善用户体验,在首屏加载过程中显示一个加载动画,避免用户看到空白页面。 在 `App.vue` 中添加加载动画逻辑: ```html <template> <div id="app"> <transition name="fade"> <div v-if="loading" class="loading">Loading...</div> </transition> <router-view v-if="!loading" /> </div> </template> <script> export default { data() { return { loading: true, }; }, mounted() { setTimeout(() => { this.loading = false; }, 3000); // 根据实际加载时间调整 }, }; </script> <style scoped> .loading { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: #fff; display: flex; justify-content: center; align-items: center; z-index: 9999; } .fade-enter-active, .fade-leave-active { transition: opacity 0.5s; } .fade-enter, .fade-leave-to { opacity: 0; } </style> ``` ##### 5. 使用懒加载技术 对非关键路径上的组件进行懒加载,延迟加载部分资源,优先加载核心内容。 例如,使用异步导入方式加载路由组件: ```javascript const HomeView = () => import(/* webpackChunkName: "home" */ '../views/HomeView.vue'); ``` ##### 6. 图片资源优化 对于图片资源,可以通过以下方式进一步优化: - 使用现代图像格式(如 WebP) -图进行压缩处理 - 使用懒加载技术(如 Intersection Observer) #### 总结 通过上述方法,可以显著减小 `chunk-vendors.js` 文件的体积,提升页面的首次加载速度,从而减少或消除白屏现象。结合 CDN 加速、代码拆分、Gzip 压缩和首屏动画等手段,可以为用户提供更流畅的体验。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值