記一次react前端項目打包優化

前文

以前一年多前接手的一個react項目,前段時間由於作業務中臺項目,對公司現有的應用項目作中臺化改造,這期間將項目部署到uat環境,
測試期間,測試小妹妹和產品大叔都吐槽進入uat項目的時候要load好久,白屏時間超過30s,體驗不好,
生產不至於這麼慢但也是白屏時間挺長的,因此減小白屏時間增長用戶體驗成爲了當務之急。
複製代碼

分析

經過控制檯判斷加載資源時間還有資源大小

資源加載時間和大小

經過開發者工具能夠看到白屏的主要緣由在於bundle.js這個打包後的文件過大,達到3.6M
加上uat環境帶寬等問題的話,光加載這個bundle.js就花了30s+,因此白屏時間太長,用戶體驗差
要解決這個問題就得從這個bundle.js入手
複製代碼

經過webpack-bundle-analyzer來分析主要是哪些模塊過大

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const webpackConfigDev = {
    plugins: [
        ......
        new BundleAnalyzerPlugin({ analyzerPort: 3012 }),
    ]
}
複製代碼

本地開發打包結果

這是本地開發時候打包的狀況,沒有gzip的狀況下是這麼大的,本地開發編譯打包也是挺慢的
從上圖看能夠分析出幾個比較大的模塊,其中一個最大的是echarts,另外就是源文件src目錄下的代碼
因此優化分爲三步來走:
1.優化echarts;
2.優化src下的業務代碼;
3.對打包後的文件進行gzip壓縮;
複製代碼

優化

優化echarts

echarts在項目中用到的地方很多,可是業務平時不多用到對應的模塊,整個打包進去bundle.js只會讓整個包變大
思路是echarts文件不打包進bundle.js,採用cdn的方法引入
複製代碼

優化echarts相關代碼

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');
複製代碼

優化src文件

對於用戶來講,可能每次操做的時候只操做對應的幾個模塊,其餘模塊不多操做到,若是可以按需加載那就能夠化整爲零
每次加載當前模塊的chunk,既不影響用戶使用,又減小加載的資源
參考了一下其餘文章,決定採用react-loadable進行切割劃分,按路由來切割資源
複製代碼

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
複製代碼

gzip壓縮

項目是用的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文件,使用正常,成功
複製代碼

2020.6.8更新

經過cdn引入echart中原先的寫法會讀取不到echart的資源,排查了一下從新作了修改
能夠在控制檯模擬是否能獲取到echart的方法進行調試
原先的    var myChart = this.$echarts.init(this.refs.char,'crm');
改版後    var myChart = window.echarts.init(this.refs.char,'crm');
複製代碼
相關文章
相關標籤/搜索