簡單幾步助你優化React應用包體

本文從屬於筆者的Web前端入門與最佳實踐 中的React入門與最佳實踐系列。本文首發於簡單幾步助你優化React應用包體 - 某熊的全棧之路 - SegmentFault,考慮到專欄知識體系的完善轉發到了這裡。

Bundle Size

前端項目中,特別是移動環境下,我們特別關心用戶的載入速度。載入速度的限制一個是並發鏈接數,受限於HTTP 1.1協議,瀏覽器的並發連接數存在一定限制,不過我們可以利用Webpack等模塊打包工具將模塊打包到一個文件中(如這裡推薦筆者的Webpack2 React Redux Boilerplate)。此時就會面臨另一個問題,首屏載入時候包體過大,而本章節就關注於基於React的項目打包編譯之後的包體大小優化。我們來看下未進行任何優化操作下的包體大小,也就是開發環境下的包體大小:

Modules Analysis

在優化之前,我們首先需要了解我們包體的模塊組成,是否存在某些模塊是可以進行非同步載入的,這裡筆者可以使用Webpack Dashboard自帶的模塊列表:

這裡我們發現ECharts佔用了較大的份額,不過實際上ECharts所支持的圖表模塊並不需要首屏展示,而是用戶點擊之後的展示,因此這樣的模塊可以進行非同步載入。另外,我們可以使用專門的Webpack Stats Analyzer工具進行分析:

添加合適的插件

plugins: [n new webpack.DefinePlugin({ // <-- key to reducing Reacts sizen process.env: {n NODE_ENV: JSON.stringify(production)n }n }),n new webpack.optimize.DedupePlugin(), //dedupe similar code n new webpack.optimize.UglifyJsPlugin(), //minify everythingn new webpack.optimize.AggressiveMergingPlugin()//Merge chunks n ],n

添加了這些插件之後,可以明顯減少包體大小:

使用GZip壓縮

先看看效果,還是很明顯的:

編譯時壓縮

npm install compression-webpack-plugin --save-devnn plugins: [n new webpack.DefinePlugin({ n process.env: {n NODE_ENV: JSON.stringify(production)n }n }),n new webpack.optimize.DedupePlugin(),n new webpack.optimize.UglifyJsPlugin(),n new webpack.optimize.AggressiveMergingPlugin(),n new CompressionPlugin({ <-- Add thisn asset: "[path].gz[query]",n algorithm: "gzip",n test: /.js$|.css$|.html$/,n threshold: 10240,n minRatio: 0.8n })n ]n

最後,我們需要設置Express進行合適的路徑轉發:

app.get(*.js, function (req, res, next) {n req.url = req.url + .gz;n res.set(Content-Encoding, gzip);n next();n});n

動態Gzip

筆者使用Express搭建服務端渲染服務,可以添加壓縮插件:

//Simply do this to add dynamic gzipping (not preferred)nnpm install compression --save //installnvar compression = require(『compression』); //import to express appnapp.use(compression());//add this as the 1st middlewaren

不過這種方式的缺陷是增加了運行時的伺服器負載,因此不是很推薦。

推薦閱讀:

讀懂webpack生成的26行代碼
webpack 打包JS 的運行原理
淺析 Webpack 插件化設計
Webpack工程化解決方案easywebpack
你的Tree-Shaking並沒什麼卵用

TAG:React | webpack | 前端性能优化 |