以前一年多前接手的一個react項目,前段時間由於作業務中臺項目,對公司現有的應用項目作中臺化改造,這期間將項目部署到uat環境,
測試期間,測試小妹妹和產品大叔都吐槽進入uat項目的時候要load好久,白屏時間超過30s,體驗不好,
生產不至於這麼慢但也是白屏時間挺長的,因此減小白屏時間增長用戶體驗成爲了當務之急。
複製代碼
經過開發者工具能夠看到白屏的主要緣由在於bundle.js這個打包後的文件過大,達到3.6M
加上uat環境帶寬等問題的話,光加載這個bundle.js就花了30s+,因此白屏時間太長,用戶體驗差
要解決這個問題就得從這個bundle.js入手
複製代碼
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin const webpackConfigDev = { plugins: [ ...... new BundleAnalyzerPlugin({ analyzerPort: 3012 }), ] } 複製代碼
這是本地開發時候打包的狀況,沒有gzip的狀況下是這麼大的,本地開發編譯打包也是挺慢的
從上圖看能夠分析出幾個比較大的模塊,其中一個最大的是echarts,另外就是源文件src目錄下的代碼
因此優化分爲三步來走:
1.優化echarts;
2.優化src下的業務代碼;
3.對打包後的文件進行gzip壓縮;
複製代碼
echarts在項目中用到的地方很多,可是業務平時不多用到對應的模塊,整個打包進去bundle.js只會讓整個包變大
思路是echarts文件不打包進bundle.js,採用cdn的方法引入
複製代碼
1.入口文件index.html這裏直接用script直接引入cdn的echarts文件 <head> <meta charset="UTF-8"> <meta http-equiv="Cache-Control" content="max-age=604800" /> <script src="https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts.min.js"></script> <title>TCRM</title> </head> <body> 2.使用echarts的地方改成下面這樣引入 原先的 var myChart = echarts.init(this.refs.char,'crm'); 改版後 var myChart = this.$echarts.init(this.refs.char,'crm'); 複製代碼
對於用戶來講,可能每次操做的時候只操做對應的幾個模塊,其餘模塊不多操做到,若是可以按需加載那就能夠化整爲零
每次加載當前模塊的chunk,既不影響用戶使用,又減小加載的資源
參考了一下其餘文章,決定採用react-loadable進行切割劃分,按路由來切割資源
複製代碼
原先寫法,組件引入 import Dashboard from './components/Dashboard'; 使用react-loadable後 import Loadable from 'react-loadable'; const LoadingFun = () => { return <div className="center-div"><Spin spinning={true} size="large" tip="加載中..."/></div>; }; const Dashboard = Loadable({loader: () => import('./components/Dashboard'), loading: LoadingFun}); webpack相關 const webpackConfigBase = { ...... output: { path: resolve('./dist'), filename: 'bundle.[hash:6].js', chunkFilename: 'chunks/[name].[hash:6].js', } } 複製代碼
本地運行分chunks打包 javascript
1.打包樣式問題,全部的css打包到bundle.css中,可是採用按路由打包後測試的小妹妹反饋樣式很奇怪 看了一下加載的資源,發現確實沒有打包到不一樣路由下的樣式,檢查了一下,發現是webpack配置裏面要配合改一下 const webpackConfigBase = { ...... plugins: [ // 提取css //原先的 new ExtractTextPlugin('bundle.[hash:6].css'), new ExtractTextPlugin({filename: 'bundle.[hash:6].css', allChunks: true}), // 增長一個allChunks:true ] } 2.chunk的名字問題,先要指定對應的chunkName參考 https://github.com/mrdulin/blog/issues/43 複製代碼
項目是用的nginx作代理調用打包後的資源,因此能夠考慮在nginx這一層增長配置配合gzip文件
複製代碼
gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 9; gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json; gzip_disable "MSIE [1-6]\."; gzip_vary on; 複製代碼
echarts經過cdn引入,成功
bundle.js體積大大減少,加載時間也由原先的30s+降到了3s+,生產環境帶寬更高會更快,成功
切換路由加載對應的chunk文件,使用正常,成功
複製代碼
經過cdn引入echart中原先的寫法會讀取不到echart的資源,排查了一下從新作了修改 能夠在控制檯模擬是否能獲取到echart的方法進行調試 原先的 var myChart = this.$echarts.init(this.refs.char,'crm'); 改版後 var myChart = window.echarts.init(this.refs.char,'crm'); 複製代碼