• Create-React-app项目首屏加载优化(二)--CDN加速


    之前,通过gzip的方式将访问速度从40多秒减少到7秒左右,但是仍然很慢。传送门

    因为使用的服务器的带宽只有1M,所以即使gzip压缩后只有700K左右,但是仍然需要5秒左右的传输时间。

    解决方法:1.缩小打包后的体积(减少至300K左右)2.将打包后的文件夹上传至腾讯云COS

    项目说明

    1. 项目是使用Create-React-app创建的,没有进行eject操作,所以需要使用react-app-rewiredcustomize-cra覆盖默认的配置。
    2. 项目使用的是antd@3.x版本,对于antd icon没有实现按需加载,虽然在antd@4.x中修复了这个问题,但是迁移组件库的成本过大,所以只能使用antd@3.x
    3. 项目已经开启了gzip压缩,具体操作可以见之前一篇博客。
    4. 建议安装webpack-bundle-analyzer来帮助分析打包后的文件各模块大小

    安装方法 npm install webpack-bundle-analyzer -D

    修改config-ouverrides.js

    const { override, fixBabelImports, addWebpackExternals, addWebpackPlugin } = require('customize-cra');
    const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
    
    module.exports = override(
    		// antd按需加载
        fixBabelImports('import', {
          libraryName: 'antd',
          libraryDirectory: 'es',
          style: 'css',
        }),
        addWebpackPlugin(
          new BundleAnalyzerPlugin({
            analyzerMode: 'static', //输出静态报告文件report.html,而不是启动一个web服务
          })
        )
    );
    

    具体步骤

    1.缩小打包后的体积(CDN加载)

    项目有数据可视化的需求,所以使用了@antv/g2作为可视化引擎。(echarts同理)

    可以看见打包后的文件中,@antv/g2@antv/data-set占据了较大的体积。

    解决方法,将@antv/g2@antv/data-set不做打包处理,而是采用CDN加载。

    1. 修改index.html,通过script标签加载@antv/g2@antv/data-set
    <script src="https://gw.alipayobjects.com/os/lib/antv/g2/4.0.10/dist/g2.min.js"></script>
    <script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.data-set-0.11.1/dist/data-set.js"></script>
    
    1. 使用addWebpackExternals方法修改external
    const { override, fixBabelImports, addWebpackExternals, addWebpackPlugin } = require('customize-cra');
    const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
    
    module.exports = override(
        // 按需加载
        fixBabelImports('import', {
          libraryName: 'antd',
          libraryDirectory: 'es',
          style: 'css',
        }),
        addWebpackPlugin(
          new BundleAnalyzerPlugin({
            analyzerMode: 'static', //输出静态报告文件report.html,而不是启动一个web服务
          })
        ),
        addWebpackExternals(
          {
          // 不做打包处理配置,如直接以cdn引入的
          '@antv/g2': 'window.G2',
          "@antv/data-set": "window.DataSet",
          // 'echarts': 'window.echarts' 如果使用的是echarts的话。
          }
        ),
    );
    

    此时再执行build,原来654KB的js文件(gizp压缩后)现在只有363 KB(gizp压缩后)

    现在gzip压缩后最大的js文件有363KB,但是由于服务器带宽只有1M,首屏加载时间依然需要4秒左右。

    之后,笔者尝试过将antd组件库也改为CDN加载,打包后只有60KB左右,但是出现了一些问题,未能实现。看到一篇博文(https://www.cnblogs.com/cxscode/p/8075125.html),可能是解决的办法,但是由于项目过大,全部修改工作量太大,所以没有尝试这篇博文中提到的方法。如果有感兴趣的小伙伴可以尝试一下,欢迎评论区交流。

    我们可以看到,现在的chunk.js文件中,体积最大的部分是antd的图标库。因为采用的是3.x版本,没有实现图标按需引入,而且好像就算你项目中没有直接使用icon,只要你使用了例如select等内置了图标的组件也会引入全部图标库,而升级到4.x的成本太大,基本上缩小打包文件体积进入了优化的深水区。

    2.将打包后的文件上传至cdn

    既然主要矛盾是服务器带宽小,文件传输慢,那就采用CDN加速。

    笔者使用的是腾讯云COS,这边以COS为例。

    前提工作

    首先,你需要开通对象存储,创建存储桶,存储桶名称为bucket-xxxxxxxxx格式,前面是自定义名称,后面为appid

    然后,开通默认cdn加速域名服务

    这边获取到了源站域名和加速域名,接下来设置publicPath的时候使用源站域名。

    设置publicPath

    const { override, fixBabelImports, addWebpackExternals, addWebpackPlugin } = require('customize-cra');
    const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
    
    module.exports = override(
        // 按需加载
        fixBabelImports('import', {
          libraryName: 'antd',
          libraryDirectory: 'es',
          style: 'css',
        }),
        addWebpackPlugin(
          new BundleAnalyzerPlugin({
            analyzerMode: 'static', //输出静态报告文件report.html,而不是启动一个web服务
          })
        ),
        addWebpackExternals(
          {
          // 不做打包处理配置,如直接以cdn引入的
          '@antv/g2': 'window.G2',
          "@antv/data-set": "window.DataSet",
          }
        ),
        (config) => {
          config.output.publicPath = "http://bucket-11111111.cos.ap-nanjing.myqcloud.com/cdn/"
          return config;
        }
    );
    

    服务器下载COSCMD工具

    1. 服务器下载COSCMD工具
    2. 配置参数,设置SECRET_ID,SECRET_KEY,BucketName_appid(也就是存储桶名称),REGION
    3. 删除原先的打包后的文件(如果存在的话)
    4. 上传新的打包后的文件

    官方文档关于COSCMD的介绍已经很详细了,笔者就不再复制粘贴了,第3、4步骤写到部署脚本中即可,如果使用的是Jenkins的话,可以参考以下代码

    pipeline {
        agent any
        stages {
            stage('Build') { 
                steps {
                    sh 'cnpm install' 
                    sh 'npm run build'
                }
            }
            
            stage('Deploy') { 
                steps {
                    sh 'rm -rf /var/www/html/*'
                    sh 'cp -R ./build/* /var/www/html'
                    sh 'coscmd delete cdn/static -f'
                    sh 'coscmd upload -r /var/www/html/static cdn/'
                    sh 'nginx -s reload'
                }
            }
        }
    }
    
    

    最终效果

    基本上可以在两秒左右完成加载。

  • 相关阅读:
    时间处理得到UTC时间
    java数据同步陷阱
    360公司2016笔试题
    YTU 1439: 2.4.5 Fractions to Decimals 分数化小数
    YTU 2422: C语言习题 n个数逆序
    YTU 2421: C语言习题 矩形法求定积分
    YTU 2427: C语言习题 整数排序
    YTU 2832: 使用指针访问数组元素--程序填空
    YTU 1050: 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换
    HDU 1069:Monkey and Banana
  • 原文地址:https://www.cnblogs.com/njuclc/p/13359388.html
Copyright © 2020-2023  润新知