之前,通過gzip的方式將訪問速度從40多秒減少到7秒左右,但是仍然很慢。傳送門
因為使用的服務器的帶寬只有1M,所以即使gzip壓縮后只有700K左右,但是仍然需要5秒左右的傳輸時間。
解決方法:1.縮小打包后的體積(減少至300K左右)2.將打包后的文件夾上傳至騰訊雲COS
項目說明
- 項目是使用
Create-React-app
創建的,沒有進行eject
操作,所以需要使用react-app-rewired
與customize-cra
覆蓋默認的配置。 - 項目使用的是
antd@3.x
版本,對於antd icon沒有實現按需加載,雖然在antd@4.x
中修復了這個問題,但是遷移組件庫的成本過大,所以只能使用antd@3.x
- 項目已經開啟了gzip壓縮,具體操作可以見之前一篇博客。
- 建議安裝
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加載。
- 修改
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>
- 使用
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工具
- 服務器下載COSCMD工具
- 配置參數,設置SECRET_ID,SECRET_KEY,BucketName_appid(也就是存儲桶名稱),REGION
- 刪除原先的打包后的文件(如果存在的話)
- 上傳新的打包后的文件
官方文檔關於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'
}
}
}
}
最終效果
基本上可以在兩秒左右完成加載。