- 原文地址:webpack & HTTP/2
- 原文作者:Tobias Koppers
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:薛定諤的貓
- 校對者:perseveringman、HydeSong
webpack & HTTP/2
讓我們從 HTTP/2 的一個傳言開始:
有了 HTTP/2,你就不再需要打包模組了。
HTTP/2 可以多路複用,所有模組都可以並行使用同一個連線,因此多個請求不再需要多餘的往返開銷。每個模組都可以獨立快取。
很遺憾,現實並不如意。
以前的文章
下面的文章詳細解釋了相關資訊,並且做了一些實驗來驗證。你可以閱讀它們(或者跳過它們,只看總結)。
文章主旨:
- 相比拼接為一個檔案,多個檔案傳輸仍然有 協議開銷(protocol overhead)。
- 相比多個小檔案,單檔案方式對壓縮更友好。
- 相比處理單個大檔案,伺服器處理多個小檔案較慢。
因此我們需要在兩者中間取得一個折中。我們將模組分為 n 個包,n 大於 1,小於模組數。改變其中一個模組使其快取失效,因為相應的包只是整個應用的一部分,其它的包的快取仍然有效。
更多的包意味著快取命中率更高,但不利於壓縮。
AggressiveSplittingPlugin
webpack 2 為你提供了這樣的工具。webpack 內部大多都是這樣,將一組模組組裝成塊(chunk)輸出一個檔案。我們還有一個優化階段可以改變這些塊(chunk),只是需要一個外掛來做這個優化。
外掛 AggressiveSplittingPlugin 將原始的塊分的更小。你可以指定你想要的塊大小。它提高了快取,但不利於壓縮(對 HTTP/1 來說也影響傳輸時間)。
為了結合相似的模組,它們在分離之前會按照路徑的字母順序排序。通常在同一目錄下的檔案往往是相關的,從壓縮來看也是一樣。通過這種排序,它們也就能分離到相同的塊中了。
對於 HTTP/2 我們現在有高效的分塊方式了。
修改應用
但這還沒結束。當應用更新時我們要儘量複用之前建立的塊。因此每次 AggressiveSplittingPlugin 都能夠找到一個合適的塊大小(在限制內),並將塊的模組(modules)和雜湊(hash)儲存到 records 中。
Records 是 webpack 編譯過程中編譯狀態的概念,可以通過 JSON 檔案存取。
當再次呼叫 AggressiveSplittingPlugin,在嘗試分離剩餘模組之前,它會先嚐試從 records 中恢復塊。這就確保已快取的塊能夠被複用。
啟動和服務(Bootstrapping and Server)
使用這項技術的應用不再輸出包含在 HTML 檔案中的單獨檔案,相反,它輸出多個需要被載入的塊(chunk),應用就能使用多個 script 標籤(並行)載入每個塊。就像這樣:
<script src="1ea296932eacbe248905.js"></script>
<script src="0b3a074667143853404c.js"></script>
<script src="0dd8c061aff2a2791815.js"></script>
<script src="191b812fa5f7504151f7.js"></script>
<script src="08702f45497539ef6ea6.js"></script>
<script src="195c9326275620b0e9c2.js"></script>
<script src="19817b3a0378aedb2143.js"></script>
<script src="0e7a65e649387d773247.js"></script>
<script src="13167c9702de79d2f4fd.js"></script>
<script src="1154be40ff0e8dd16e9f.js"></script>
<script src="129ce3c198a25d9ace74.js"></script>
<script src="032d1fc9a213dfaf2c79.js"></script>
<script src="07df084bbafc95c1df47.js"></script>
<script src="15c45a570bb174ae448e.js"></script>
<script src="02099ada43bbf02a9f73.js"></script>
<script src="17bc99aaed6b9a23da78.js"></script>
<script src="02d127598b1c99dcd2d0.js"></script>複製程式碼
webpack按時間先後順序輸出這些塊。最舊的檔案先執行,最新的在最後。瀏覽器可以先執行已被快取的塊,同時載入最新的檔案 -- 舊檔案更可能已經被快取。
當 HTML 檔案被請求時,HTTP/2 服務端推送可以將這些塊推送給客戶端。也是因為舊檔案更可能已經被快取,最好能先推送最新的檔案。如果已經有快取,客戶端可以取消服務端的推送,但這需要一次往返。
webpack 將程式碼分離用於 按需載入,可以處理並行請求。
結論
webpack 2 為你提供了用於 HTTP/2 的,能改善快取和傳輸的工具。不用擔心你的技術棧不面向未來了。
注意 AggressiveSplittingPlugin 仍然是實驗特性。
我對你的使用體驗很感興趣哦~
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、React、前端、後端、產品、設計 等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。