1. 程式人生 > 實用技巧 >Create-React-app專案首屏載入優化(二)--CDN加速

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. 專案使用的是[email protected]版本,對於antd icon沒有實現按需載入,雖然在[email protected]中修復了這個問題,但是遷移元件庫的成本過大,所以只能使用[email protected]
  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 'echo y | coscmd delete cdn/static'
                sh 'coscmd upload -r /var/www/html/static cdn/'
                sh 'nginx -s reload'
            }
        }
    }
}

最終效果

基本上可以在兩秒左右完成載入。