使用 HTTP 缓存防止不必要的网络请求
原文
通過網絡獲取資源既緩慢又昂貴:
- 大型響應需要瀏覽器和服務器之間的多次往返。
- 直到所有關鍵資源都完全下載后,您的頁面才會加載。
- 如果一個人使用有限的移動數據計劃訪問您的網站,那么每個不必要的網絡請求都是在浪費他們的錢。
如何避免不必要的網絡請求? 瀏覽器的 HTTP 緩存是您的第一道防線。 它不一定是最強大或最靈活的方法,它對緩存響應的生命周期的控制有限,但它是有效的,所有瀏覽器都支持它,并且不需要太多工作。
實際上沒有一個稱為 HTTP 緩存的 API。 它是 Web 平臺 API 集合的總稱。 所有瀏覽器都支持這些 API:
- Cache-Control
- ETag
- Last-Modified
HTTP cache 的工作原理
瀏覽器發出的所有 HTTP 請求都首先路由到瀏覽器緩存,以檢查是否存在可用于滿足請求的有效緩存響應。如果匹配,則從緩存中讀取響應,從而消除網絡延遲和傳輸產生的數據成本。
HTTP 緩存的行為由請求標頭和響應標頭的組合控制。在理想情況下,您可以控制 Web 應用程序的代碼(將確定請求標頭即 HTTP request headers)和 Web 服務器的配置(將確定響應標頭即 HTTP response headers)。
Request headers: stick with the defaults (usually)
雖然有許多重要的標頭應該包含在您的 Web 應用程序的傳出請求中,但瀏覽器在發出請求時幾乎總是代表您進行設置。 影響檢查新鮮度的請求標頭,如 If-None-Match 和 If-Modified-Since 只是基于瀏覽器對 HTTP 緩存中當前值的理解而出現。
這是個好消息——這意味著您可以繼續在 HTML 中包含諸如下列例子之類的標簽,并且瀏覽器會自動為您處理 HTTP 緩存,而無需額外的努力。
<img src="my-image.png">Response headers: configure your web server
HTTP 緩存設置中最重要的部分是您的 Web 服務器添加到每個傳出響應的標頭。 以下標頭都會影響有效的緩存行為:
-
Cache-control: 服務器可以返回一個 Cache-Control 指令來指定瀏覽器和其他中間緩存應該如何緩存單個響應以及緩存多長時間。
-
ETAG: 當瀏覽器發現過期的緩存響應時,它可以向服務器發送一個小令牌(通常是文件內容的哈希)以檢查文件是否已更改。 如果服務器返回相同的令牌,則文件是相同的,無需重新下載。
-
Last-Modified: 此標頭與 ETag 的用途相同,但使用基于時間的策略來確定資源是否已更改,這與 ETag 的基于內容的策略相反。
默認情況下,某些 Web 服務器內置支持設置這些標頭,而其他 Web 服務器則完全保留標頭,除非您明確配置它們。 如何配置標頭的具體細節因您使用的 Web 服務器而異,您應該查閱服務器的文檔以獲得最準確的詳細信息。
省略 Cache-Control 響應標頭不會禁用 HTTP 緩存! 相反,瀏覽器有效地猜測哪種類型的緩存行為對給定類型的內容最有意義。 您可能需要更多的控制權,因此請花時間配置您的響應標頭。
在配置 Web 服務器的響應標頭時,您應該涵蓋兩個重要的場景。
Long-lived caching for versioned URLs
假設您的服務器指示瀏覽器將 CSS 文件緩存 1 年(Cache-Control: max-age=31536000),但您的設計人員剛剛進行了一個需要立即推出的緊急更新。您如何通知瀏覽器更新文件的“陳舊”緩存副本?你不能,至少不能不改變資源的 URL。在瀏覽器緩存響應后,緩存版本將一直使用,直到它不再是最新的,這由 max-age 或 expires 決定,或者直到它因某些其他原因從緩存中被驅逐——例如,用戶清除他們的瀏覽器緩存。因此,在構建頁面時,不同的用戶最終可能會使用不同版本的文件:剛剛獲取資源的用戶使用新版本,而緩存較早(但仍然有效)副本的用戶使用其舊版本回復。您如何獲得兩全其美:客戶端緩存和快速更新?您更改資源的 URL 并強制用戶在其內容更改時下載新響應。通常,您可以通過在文件名中嵌入文件的指紋或版本號來實現這一點,例如 style.x234dff.css。
當響應包含“指紋”或版本信息且其內容永遠不會改變的 URL 請求時,請將 Cache-Control: max-age=31536000 添加到您的響應中。
設置這個值告訴瀏覽器,當它需要在接下來的一年內的任何時候(31,536,000 秒;支持的最大值)加載相同的 URL 時,它可以立即使用 HTTP 緩存中的值,而無需向網絡發出請求 你的網絡服務器。 太好了 - 您立即獲得了避免網絡帶來的可靠性和速度!
像 webpack 這樣的構建工具可以自動化將哈希指紋分配給資產 URL 的過程。
Server revalidation for unversioned URLs
不幸的是,并非您加載的所有 URL 都是版本化的。
也許您無法在部署 Web 應用程序之前包含構建步驟,因此您無法向資產 URL 添加哈希值。 并且每個 Web 應用程序都需要 HTML 文件——這些文件(幾乎!)永遠不會包含版本信息,因為如果他們需要記住要訪問的 URL 是 https://example.com,那么沒有人會費心使用您的 Web 應用程序 /index.34def12.html。 那么你能對這些 URL 做些什么呢?
這是您需要承認失敗的一種情況。 單獨的 HTTP 緩存不足以完全避開網絡 request. 但是你可以采取一些步驟來確保網絡請求盡可能快, 并盡可能高效。
以下 Cache-Control 值可以幫助您微調未版本控制的 URL 的緩存位置和方式:
- no-cache: 這會指示瀏覽器每次使用 URL 的緩存版本之前都必須與服務器重新驗證。
- no-store: 這會指示瀏覽器和其他中間緩存(如 CDN)從不存儲文件的任何版本。
- private: 瀏覽器可以緩存文件,但中間緩存不能。
- public: 響應可以由任何緩存存儲。
Etag 使用例子
瀏覽器從服務器請求 /file 并包含 If-None-Match 標頭以指示服務器僅在服務器上文件的 ETag 與瀏覽器的 If-None-Match 值不匹配時才返回完整文件。 在這種情況下,這 2 個值確實匹配,因此服務器返回 304 Not Modified 響應,并說明文件應緩存多長時間(Cache-Control: max-age=120)。
總結
HTTP Cache 是一種提高負載性能的有效方式,因為它減少了不必要的網絡請求。 它在所有瀏覽器中都受支持,并且不需要太多設置。
以下 Cache-Control 配置是一個好的開始:
-
Cache-control: no-cache - 對于每次使用前應與服務器重新驗證的資源
-
Cache-control:no-store: - 不應該緩存的資源
-
Cache-control: max-age=31536000:版本化資源
總結
以上是生活随笔為你收集整理的使用 HTTP 缓存防止不必要的网络请求的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux中touch命令使用(创建文件
- 下一篇: 让 SAP Spartacus 某些 C