測試同學問我為什麼每次讓我清快取(聊聊瀏覽器的快取)

快樂的開發者發表於2022-01-21

前言

最近一個好奇的測試同學問我,你們前端開發完成後,每次都讓我們清快取或者Ctrl+f5強制重新整理,我能不能每次不用強制重新整理,就能看到你們更新的內容呢。我說是可以做到的,我來跟你講講瀏覽器的快取策略。我相信應該有不少的同學在工作中都會遇到這種情況,讓你的測試同學清快取等。

快取

瀏覽器快取是為了節約網路的資源加速瀏覽,瀏覽器在使用者磁碟上對最近請求過的文件進行儲存,當訪問者再次請求這個頁面時,瀏覽器就可以從本地磁碟或記憶體中顯示文件,這樣就可以加速頁面的閱覽。

瀏覽器快取主要有兩類:強快取:cache-controlExpires 快取協商:Last-modifiedEtag

所有的快取策略都是通過http header裡設定的。

瀏覽器快取.png

強快取

當瀏覽器去獲取資源的時候,不給伺服器發請求,直接從快取中讀取。

Expires(過期時間)

Expires(快取過期時間)是http1.0的產物,用來指定資源的到期時間,是服務端返回的時間點。

image.png

從上面圖我們可以看出在Expires: Thu, 20 Jan 2022 07:50:17 GMT在這之後會過期,請求改資源不會從快取中獲取。

缺點: 時間的判斷是通過本地判讀的,如果本地時間調大了,快取可能會失效。

Cache-Control

Cache-Control是http1.1控制快取的重要欄位,如果Cache-Control在,它的優先順序會比Expires高。常用的值如下

名稱 描述
public 表示可以被客戶端和代理伺服器快取
private 表示只可以被客戶端快取
max-age=30 單位為秒(s), 表示30s之內,從快取中獲取
s-maxage=30 max-age一樣,表示只在代理中生效
no-sotre 不快取任何響應
no-cache 資源被快取,但馬上失效,下次請求會通過協商快取驗證資源是否過去
max-stale=30 在30s之內,快取過期也從快取中讀取

協商快取

協商快取就是強制快取失效後,瀏覽器攜帶快取標識向伺服器發起請求,由伺服器根據快取標識決定是否使用快取的過程,主要有兩組配合使用:

  • Last-ModifiedIf-Modified-Since
  • EtagIf-None-Match

Last-Modified和If-Modified-Since

瀏覽器在第一次訪問資源的時候,伺服器返回資源的同事,會在Response header中新增Last-Modified的key,表示該資源最後修改時間,瀏覽器接收後快取檔案header,下次請求該資源,瀏覽器會檢測到有Last-Modified這個請求頭,於是在請求中會新增If-Modified-Since這個請求頭,值就是之前Last-Modified中的值。伺服器收到請求後,會根據If-Modified-Since中的值去判斷資源是否更新。

如果值相等,就返回304狀態碼和空的響應體,瀏覽器收到後會通過快取獲取。可以看下圖

image.png

如果不相等,就返回內容和200的狀態碼。

image.png

EtagIf-None-Match

Etag是伺服器響應請求時,返回當前資原始檔的一個唯一標識(由伺服器生成),只要資源有變化,Etag就會重新生成。瀏覽器在下一次載入資源向伺服器傳送請求時,會將上一次返回的Etag值放到Request header裡的If-None-Match,伺服器只需要比較客戶端傳來的If-None-Match跟自己伺服器上該資源的ETag是否一致,就能很好地判斷資源相對客戶端而言是否被修改過了。

如果值相等,就返回304狀態碼和空的響應體,瀏覽器收到後會通過快取獲取。可以看下圖

image.png

如果不相等,就返回內容和200的狀態碼。

image.png

注意ETag和If-None-Match優先順序高於Last-Modified和If-Modified-Since,同時存在則只有ETag和If-None-Match生效。

應用部署設定規則

我們知道了瀏覽器的快取之後,在常見的web開發中我們應該怎麼設定呢。

現在大多數的應用是通過webpack打包的,打包生成的資源名稱會帶上hash值。下面是打包後的檔案

image.png

我們可以遵循之下規則

  • index.html入口檔案不加強制快取,設定成協商快取
  • js 資源線上上環境可以設定成強快取。

因為我們每次打包之後,入口檔案會有變化,所以協商快取會失效,會重新從伺服器獲取新的資源。而對應的js資源有hash的變化,所以有變化,會從伺服器中獲取。

結束語

瀏覽器的快取策略,我們就說到這了,快來學習下,跟你的測試小夥伴說一說。

如果你覺得該文章不錯,不妨

1、點贊,讓更多的人也能看到這篇內容

2、關注我,讓我們成為長期關係

3、關注公眾號「前端有話說」,裡面已有多篇原創文章,和開發工具,歡迎各位的關注,第一時間閱讀我的文章

相關文章