搜尋
首頁web前端js教程使用React和Webpack如何優化打包?

使用React和Webpack如何優化打包?

Jun 11, 2018 am 10:09 AM
reactwebpack

本篇文章主要介紹了淺談React Webpack 構建打包優化,現在分享給大家,也給大家做個參考

本文介紹了React Webpack 構建打包優化,分享給大家,具體如下:

使用babel-react-optimize 對React 程式碼進行最佳化

檢查沒有使用的函式庫,去除import 引用

按需打包所使用的類別庫,例如lodash 、echart等等

lodash 可以採用babel-plugin-lodash 來優化。

要注意的是

在 babel-react-optimize 中使用了 babel-plugin-transform-react-remove-prop-types 這個插件。正常情況下,如果你在程式碼中沒有引用到元件的 PropTypes ,則完全沒問題。如果你的元件用到了,那麼使用該插件可能會導致問題。

具體見:

https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types#is-it-safe

#Webpack 建置打包最佳化

Webpack 建置打包存在的問題主要集中於以下兩個面向:

  1. Webpack 建置速度慢

  2. Webpack 打包後的檔案體積過大

#Webpack 建置速度慢

可以使用Webpack.DDLPlugin , HappyPack 來提高建置速度。詳見小銘在 DMP DDLPlugin 的文件。原文如下:

Webpack.DLLPlugin

新增一個webpack.dll.config.js
主要用到一個DllPlugin 插件,把一些第三方的資源獨立打包,同時放到一個manifest.json 設定檔中,

這樣在元件中更新後,就不會重新build 這些第三方的資源,

  1. 同時獨立設定dll/vendors .js 文件,提供給webpack.dll.config.js

  2. 修改package.json

在scripts 中加入: "dll": "webpack --config webpack.dll.config.js --progress --colors ", 。

執行npm run dll 以後,會在dll 目錄下生產兩個文件vendor-manifest.json ,vendor.dll.js

配置webpack.dev.config.js 文件,加入一個DllReferencePlugin 插件,並指定vendor-manifest.json 檔案

new webpack.DllReferencePlugin({
 context: join(__dirname, 'src'),
 manifest: require('./dll/vendor-manifest.json')
})

修改html

<% if(htmlWebpackPlugin.options.NODE_ENV ===&#39;development&#39;){ %>
 <script src="dll/vendor.dll.js"></script>
<% } %>

注意,需要在htmlWebpackPlugin 插件中設定NODE_ENV 參數

Happypack

透過多線程,快取等方式提升rebuild 效率https://github.com/amireh/happypack

在webpack.dev.config.js 中針對不同的資源創建多個HappyPack , 例如js 1 個,less 1 個,並設定好id

new HappyPack({
 id: &#39;js&#39;,
 threadPool: happyThreadPool,
 cache: true,
 verbose: true,
 loaders: [&#39;babel-loader?babelrc&cacheDirectory=true&#39;],
}),
new HappyPack({
 id: &#39;less&#39;,
 threadPool: happyThreadPool,
 cache: true,
 verbose: true,
 loaders: [&#39;css-loader&#39;, &#39;less-loader&#39;],
})

在module.rules 中配置use 為happypack/loader, 設定id

{
 test: /\.js$/,
 use: [
 &#39;happypack/loader?id=js&#39;
 ],
 exclude: /node_modules/
}, {
 test: /\.less$/,
 loader: extractLess.extract({
 use: [&#39;happypack/loader?id=less&#39;],
 fallback: &#39;style-loader&#39;
 })
}

減少Webpack 打包後的檔案體積大小

首先需要對我們整個bundle 進行分析,由哪些東西組成及各組成部分所佔大小。

這裡推薦 webpack-bundle-analyzer 。安裝後在webpack.dev.config.js 中加入外掛程式即可,就能在每次啟動後自動在網站開啟分析結果,如下圖

plugins.push( new BundleAnalyzerPlugin());

除此之外,還可以將打包過程輸出成json檔案

webpack --profile --json -> stats.json

然後到下面這兩個網站進行分析

  1. webpack/analyse

  2. Webpack Chart

透過上面的圖表分析可以清楚得看到,整個bundle.js 的組成部分及對應的大小。

解決bundle.js 體積過大的解決想法如下:

  1. 生產環境啟用壓縮等插件,移除不必要插件

  2. 拆分業務代碼與第三方函式庫及公用模組

  3. webpack 開啟gzip 壓縮

  4. 按需載入

生產環境啟用壓縮等插件,移除不必要插件

確保在生產環境啟動webpack.DefinePlugin 和webpack.optimize.UglifyJsPlugin 。

const plugins = [
 new webpack.DefinePlugin({
  &#39;process.env.NODE_ENV&#39;: JSON.stringify(process.env.NODE_ENV || &#39;production&#39;)
 }),
  new webpack.optimize.UglifyJsPlugin({
  compress: {
   warnings: false,
   drop_console: false //eslint-disable-line
  }
  })   
]

分割業務程式碼與第三方函式庫及公用模組

由於專案的業務程式碼變更頻率很高,而第三方函式庫的程式碼變更則相對沒有那麼頻率。如果將業務程式碼和第三函式庫打包到同一個chunk 的話,在每次建置的時候,即使是商業程式碼只改了一行,即使第三方函式庫的程式碼沒有發生變化,會導致整個chunk 的hash 跟上一次不同。這不是我們想要的結果。我們想要的是,如果第三方函式庫的程式碼沒有變化,那麼在建置的時候也要保證對應的 hash 沒有發生變化,從而能利用瀏覽器緩存,更好的提高頁面載入效能和縮短頁面載入時間。

因此可以將第三庫的程式碼單獨拆分成 vendor chunk,與業務程式碼分開。這樣就算業務程式碼再怎麼變化,只要第三方函式庫程式碼沒有發生變化,對應的 hash 就不變。

首先entry 設定兩個app 和vendor 兩個chunk

entry: {
 vendor: [path.join(__dirname, &#39;dll&#39;, &#39;vendors.js&#39;)],
 app: [path.join(__dirname, &#39;src/index&#39;)]
},
output: {
 path: path.resolve(__dirname, &#39;build&#39;),
 filename: &#39;[name].[chunkhash:8].js&#39;
},

其中vendros.js 是自己定義的哪些第三方函式庫需要納入vendor 中,如下:

require(&#39;babel-polyfill&#39;);
require(&#39;classnames&#39;);
require(&#39;intl&#39;);
require(&#39;isomorphic-fetch&#39;);
require(&#39;react&#39;);
require(&#39;react-dom&#39;);
require(&#39;immutable&#39;);
require(&#39;redux&#39;);

然後透過CommonsChunkPlugin 拆分第三庫

plugins.push(
 // 拆分第三方库
 new webpack.optimize.CommonsChunkPlugin({ name: &#39;vendor&#39; }),
 // 拆分 webpack 自身代码
 new webpack.optimize.CommonsChunkPlugin({
  name: &#39;runtime&#39;,
  minChunks: Infinity
 })
);

上面的配置有两个细节需要注意

  1. 使用 chunkhash 而不用 hash

  2. 单独拆分 webpack 自身代码

使用 chunkhash 而不用 hash

先来看看这二者有何区别:

  1. hash 是 build-specific ,任何一个文件的改动都会导致编译的结果不同,适用于开发阶段

  2. chunkhash 是 chunk-specific ,是根据每个 chunk 的内容计算出的 hash,适用于生产

因此为了保证第三方库不变的情况下,对应的 vendor.js 的 hash 也要保持不变,我们再 output.filename 中采用了 chunkhash

单独拆分 webpack 自身代码

Webpack 有个已知问题:

webpack 自身的 boilerplate 和 manifest 代码可能在每次编译时都会变化。

这导致我们只是在 入口文件 改了一行代码,但编译出的 vendor 和 entry chunk 都变了,因为它们自身都包含这部分代码。

这是不合理的,因为实际上我们的第三方库的代码没变,vendor 不应该在我们业务代码变化时发生变化。

因此我们需要将 webpack 这部分代码分离抽离

new webpack.optimize.CommonsChunkPlugin({
   name: "runtime",
   minChunks: Infinity
}),

其中的 name 只要不在 entry 即可,通常使用 "runtime" 或 "manifest" 。

另外一个参数 minChunks 表示:在传入公共chunk(commons chunk) 之前所需要包含的最少数量的 chunks。数量必须大于等于2,或者少于等于 chunks的数量,传入 Infinity 会马上生成 公共chunk,但里面没有模块。

拆分公共资源

同 上面的拆分第三方库一样,拆分公共资源可以将公用的模块单独打出一个 chunk,你可以设置 minChunk 来选择是共用多少次模块才将它们抽离。配置如下:

new webpack.optimize.CommonsChunkPlugin({
 name: &#39;common&#39;,
 minChunks: 2,
}),

是否需要进行这一步优化可以自行根据项目的业务复用度来判断。

开启 gzip

使用 CompressionPlugin 插件开启 gzip 即可:

// 添加 gzip
new CompressionPlugin({
 asset: &#39;[path].gz[query]&#39;,
 algorithm: &#39;gzip&#39;,
 test: /\.(js|html)$/,
 threshold: 10240,
 minRatio: 0.8
})

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用Vue如何实现拦截器对token处理方法有哪些?

使用js和jQuery如何实现指定赋值方法

有关Vue中如何换肤?

以上是使用React和Webpack如何優化打包?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安裝JavaScript?如何安裝JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

在Quartz中如何在任務開始前發送通知?在Quartz中如何在任務開始前發送通知?Apr 04, 2025 pm 09:24 PM

如何在Quartz中提前發送任務通知在使用Quartz定時器進行任務調度時,任務的執行時間是由cron表達式設定的。現�...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器