• vue项目优化首评加载速度,以及白屏时间过久


    项目背景:

    测试环境的管理后台应客户需求最近加了点东西,加载的东西变多,使得整个项目变得有点臃肿了,首屏以及刷新后渲染速度变得极其缓慢。之前10s左右还能勉强接受,这次一下干到30s,整个人都崩溃了,花了点时间优化了一下。
    ​​在这里插入图片描述
    环境:vue:2.6.11,vue-cli:3.0


    splitChunks:

    看到上面图片里的文件其实并不大,最大的也就287k。
    这也是优化过的,之前都是有的最大为1m左右,在vue.config.js配置splitChunks,进行公共模块的提取,但是时间上并没有提升多少。只不过是性能优化了一点。

    chainWebpack: config => {
            if (process.env.NODE_ENV === "production") {
                config.optimization.splitChunks({
                    chunks: "all",
                    maxInitialRequests: 4,
                    cacheGroups: {
                        default: {
                            name: "common",
                            minChunks: 5, // 模块被引用2次以上的才抽离
                            priority: 1,
                            reuseExistingChunk: true, // 复用公共模块
                        },
                        vendors: {
                            // 默认拆分node_modules
                            test: /[\\/]node_modules[\\/]/,
                            minChunks: 1, // 默认1
                            priority: 10,
                            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('@', '')}`
                            }
                        },
                        elementUI: {
                            name: "chunk-elementUI", //  split elementUI into a single package
                            priority: 20, //  the weight needs to be larger than libs and app or it will be packaged into libs or app
                            test: /[\\/]node_modules[\\/]_?element-ui(.*)/, //  in order to adapt to cnpm
                        },
                        echarts: {
                            name: "chunk-echarts", //  split elementUI into a single package
                            priority: 30, //  the weight needs to be larger than libs and app or it will be packaged into libs or app
                            test: /[\\/]node_modules[\\/]_?echarts(.*)/, //  in order to adapt to cnpm
                        },
                        xlsx: {
                            name: "chunk-xlsx", //  split elementUI into a single package
                            priority: 20, //  the weight needs to be larger than libs and app or it will be packaged into libs or app
                            test: /[\\/]node_modules[\\/]_?xlsx(.*)/, //  in order to adapt to cnpm
                        },
                        editor: {
                            name: "chunk-editor", //  split elementUI into a single package
                            priority: 50, //  the weight needs to be larger than libs and app or it will be packaged into libs or app
                            test: /[\\/]node_modules[\\/]_?vue-json-editor(.*)/, //  in order to adapt to cnpm
                        },
                    },
                });
            }
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    CDN:

    通过上面的那步,文件变小了,但是对于一些文件来说echarts、XLSX、element-ui来说,还是加载有点久。配置CDN后,也就几百毫秒久加载完成了。
    先在index.html配置,顺序不要变,vue在首先引入

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="icon" href="<%= BASE_URL %>favicon.ico">
        
        <link rel="stylesheet" href="https://at.alicdn.com/t/font_830376_qzecyukz0s.css">
        <!-- 引入 element ui.css -->
        <link href="https://cdn.bootcss.com/element-ui/2.15.7/theme-chalk/index.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>  
        <script src="https://cdn.bootcss.com/element-ui/2.15.7/index.js"></script>
      </head>
      <body>
        <noscript>
          <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
        </noscript>
        <div id="app">
          
        </div>
        <!-- built files will be auto injected -->
      </body>
      <script src="https://cdn.bootcss.com/echarts/3.7.0/echarts.min.js"></script>
      <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
      
    </html>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    接下来在vue.config.js配置,element-ui上面要先把vue配置好

    configureWebpack: (config) => {
        return {
            externals:{
                'vue': "Vue",
                'echarts': 'echarts',
                'element-ui': 'ELEMENT',
                XLSX: "XLSX",
            },
            plugins: [
                new webpack.ProvidePlugin({
                    $: "jquery",
                    jQuery: "jquery",
                    "windows.jQuery": "jquery",
                }),
            ],
        };
    },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    然后把main.js引入的vue、elementui、echart、XLSX全部注释掉
    如果要用的话直接使用。例如:

    
    //某些js文件引入elementui
    ELEMENT.Message.error(error.message)
    
    //echarts
    this.myMiddleChart = echarts.init(this.$refs.myChart);//自己加的代码
    this.myMiddleChart.setOption(this.option)
    this.lineChart = echarts.init(this.$refs.lineChart);//自己加的代码
    this.lineChart.setOption(this.lineOption)
    
    let table = document.getElementById('table');
    let worksheet = XLSX.utils.table_to_sheet(table);
    let workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, 'sheet');
    // 以上四行也可以直接一行搞定,如果不需要对表格数据进行修改的话
    let workbooked = XLSX.utils.table_to_book(document.getElementById('table'))
    XLSX.writeFile(workbooked, '报表.xlsx');
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    GZIP:

    使用CDN引入,特定资源加载速度确实变快了,但是大多数文件加载还是比较慢的,加载资源也比较大。
    在vue.config.js配置如下

    configureWebpack: (config) => {
      return {
          externals:{
              'vue': "Vue",
              'echarts': 'echarts',
              'element-ui': 'ELEMENT',
              XLSX: "XLSX",
          },
          plugins: [
              new webpack.ProvidePlugin({
                  $: "jquery",
                  jQuery: "jquery",
                  "windows.jQuery": "jquery",
              }),
              new CompressionPlugin({
                  algorithm: "gzip", // 使用gzip压缩
                  test: /\.js$|\.html$|\.css$/, // 匹配文件名
                  filename: "[path].gz[query]", // 压缩后的文件名(保持原文件名,后缀加.gz)
                  minRatio: 0.8, // 压缩率小于1才会压缩
                  threshold: 10240, // 对超过10k的数据压缩
                  deleteOriginalAssets: false, // 是否删除未压缩的源文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false(比如删除打包后的gz后还可以加载到原始资源文件)
              }),
          ],      
       };
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    然后去服务器上,找到nginx,对制定的服务开始gzip压缩

     # 开启gzip    
    gzip  on;
    # 低于1kb的资源不压缩
    gzip_min_length 1k;
    # 设置压缩所需要的缓冲区大小
    gzip_buffers 4 16k;
    # 压缩级别【1-9】,越大压缩率越高,同时消耗cpu资源也越多,建议设置在4左右。
    gzip_comp_level 4;
    # 需要压缩哪些响应类型的资源,缺少自己补。
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml;
    # 配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
    gzip_disable "MSIE [1-6]\.";
    # 是否添加“Vary: Accept-Encoding”响应头,
    gzip_vary on;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    删除文件预加载:

    以上搞完之后,首屏加载速度确实有提升。
    但是页面刷新还是有点慢,mac和windows加载速度不一致,mac更慢一点。用lighthouse跑了一下,还是不行。速度的话windows10s,mac19s,还是不行。加载的空白时间还是过长。

    因为 vuecli 3默认开启 prefetch(预先加载模块),提前获取用户未来可能会访问的内容
    我看了一下,我每次刷新后回预加载11个路由,这的确很慢。体验没有那么好。于是我把这个预加载给删了

    chainWebpack: config => {
    //删除预加载
    config.plugins.delete('prefetch')
       if (process.env.NODE_ENV === "production") {
           config.optimization.splitChunks({
               chunks: "all",
               maxInitialRequests: 4,
               cacheGroups: {
                   default: {
                       name: "common",
                       minChunks: 5, // 模块被引用2次以上的才抽离
                       priority: 1,
                       reuseExistingChunk: true, // 复用公共模块
                   },
                   vendors: {
                       // 默认拆分node_modules
                       test: /[\\/]node_modules[\\/]/,
                       minChunks: 1, // 默认1
                       priority: 10,
                       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('@', '')}`
                       }
                   },
           });
       }
     },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    这样整体的加载速度,提升到3s,最快的时候1.7s就可以加载完成。
    在这里插入图片描述

    Lighthouse的分数也跑到66分,也算及格了,最开始只有33。
    在这里插入图片描述
    家里的网跑到75,绝绝子
    在这里插入图片描述

  • 相关阅读:
    “华为杯”研究生数学建模竞赛2019年-【华为杯】F题:智能飞行器航迹规划模型(中)(附优秀论文及Pyhton代码实现)
    API阶段测试
    【Vue】Vue的Mustache插值语法、v-bind指令
    不一样的纯H5C3动画爱心
    自建网盘平台搭建(源码+教程)
    Laravel 6 - 第十五章 验证器
    Arthas(1):Java诊断工具Arthas入门教程
    python笔记二【string】
    深度学习实战01-卷积神经网络(CNN)实现Mnist手写体识别
    AWS SQS, Boto3 and Python:带示例的完整指南
  • 原文地址:https://blog.csdn.net/chenacxz/article/details/126607956