做**開發離不開快取,快取分好多種:伺服器快取,第三方快取,瀏覽器快取等。其中瀏覽器快取是代價最小的,因為瀏覽器快取依賴的是客戶端,而幾乎不耗費伺服器端的資源。
讓瀏覽器做快取需要給瀏覽器傳送指定的http頭,告訴瀏覽器快取多長時間,或者堅決不要快取。作為.net的程式設計師,其實我們一直都在用這種方法,在outputcache指令中指定快取的location為client時,其實就是給瀏覽器傳送了乙個http頭,告訴瀏覽器這個url要快取多長時間,最後修改的時間。
微軟在outputcachemodule中對這些快取用到的http頭給我們進行了很好的封裝,但是了解這些http頭可以更靈活的使用它們。
1.expires(過期時間)http頭資訊
expires(過期時間) 屬性是http控制快取的基本手段,這個屬性告訴快取器:相關副本在多長時間內是新鮮的。過了這個時間,快取器就會向源伺服器傳送請求,檢查文件是否被修改。幾乎所有的快取伺服器都支援expires(過期時間)屬性;
大部分web伺服器支援你用幾種方式設定expires屬性;一般的:可以設計乙個絕對時間間隔:基於客戶最後檢視副本的時間(最後訪問時間)或者根據伺服器上文件最後被修改的時間;
expires 頭資訊:對於設定靜態檔案(例如導航欄和按鈕)可快取特別有用;因為這些修改很少,你可以給它們設定乙個特別長的過期時間,這會使你的**對 使用者變得相應非常快;他們對於控制有規律改變的網頁也很有用,例如:你每天早上6點更新新聞頁,你可以設定副本的過期時間也是這個時間,這樣快取 伺服器就知道什麼時候去取乙個更新版本,而不必讓使用者去按瀏覽器的「重新整理」按鈕。
過期時間頭資訊屬性值只能是http格式的日期時間,其他的都會被解析成當前時間「之前」,副本會過期,記住:http的日期時間必須是格林威治時間(gmt),而不是本地時間。舉例:
expires: fri, 30 oct 1998 14:19:41
雖然過期時間屬性非常有用,但是它還是有些侷限,首先:是牽扯到了日期,這樣web伺服器的時間和快取伺服器的時間必須是同步的,如果有些不同步,要麼是應該快取的內容提前過期了,要麼是過期結果沒及時更新。
還有乙個過期時間設定的問題也不容忽視:如果你設定的過期時間是乙個固定的時間,如果你返回內容的時候又沒有連帶更新下次過期的時間,那麼之後所有訪問請求都會被傳送給源web伺服器,反而增加了負載和響應時間;
2.cache-control(快取控制) http頭資訊
http 1.1介紹了另外一組頭資訊屬性:cache-control響應頭資訊,讓**的發布者可以更全面的控制他們的內容,並定位過期時間的限制。
有用的 cache-control響應頭資訊包括:
max-age=[秒] — 執行快取被認為是最新的最長時間。類似於過期時間,這個引數是基於請求時間的相對時間間隔,而不是絕對過期時間,[秒]是乙個數字,單位是秒:從請求時間開始到過期時間之間的秒數。
s-maxage=[秒] — 類似於max-age屬性,除了他應用於共享(如:**伺服器)快取
public — 標記認證內容也可以被快取,一般來說: 經過http認證才能訪問的內容,輸出是自動不可以快取的;
no-cache — 強制每次請求直接傳送給源伺服器,而不經過本地快取版本的校驗。這對於需要確認認證應用很有用(可以和public結合使用),或者嚴格要求使用最新資料的應用(不惜犧牲使用快取的所有好處);
no-store — 強制快取在任何情況下都不要保留任何副本
must-revalidate — 告訴快取必須遵循所有你給予副本的新鮮度的,http允許快取在某些特定情況下返回過期資料,指定了這個屬性,你快取記憶體,你希望嚴格的遵循你的規則。
proxy-revalidate — 和 must-revalidate類似,除了他只對快取**伺服器起作用
舉例:cache-control: max-age=3600, must-revalidate
給靜態資源(html檔案,檔案等)的repsone加上expires/cache-control header是很有效的一招。如果http response中有expires這樣的header的話,瀏覽器會cache這個資源,理想狀況下(注意,只是理想狀況),在expire date之前,不會再發http請求給server要這個資源,不過expires的值只能是乙個固定日期,比如「thu 27 nov 2008 07:00:00 gmt」,不能是乙個類似「從現在開始之後10年」這樣乙個隨機浮動的值,如果要這樣的效果,可以用cache-control這樣的header,如果 http resposne中有這樣的header:「cache-control: max-age = 100」,表示這個資源在cache中的最大壽命是100秒。一般說來這種靜態檔案永遠不應該過期,如果真的要給這個cache加上乙個期限,那我希望是 ——一萬年,「cache-control: max-age = 315360000000」
其實就應該給expires設乙個永遠不會過期的時間,比如你現在有乙個檔案叫logo.gif,需要用乙個新的logo的時候,你不要去 覆蓋原來的檔案,而把新的logo存成logo_v2.gif,讓相關網頁引用新的logo_v2.gif,這樣可以讓新老網頁同時工作,實在犯不上為了 節省儲存空間覆蓋原有檔案。
對apache伺服器,使用mod_expires,在httpd.conf或者.htaccess中加上
expiresdefault "access plus 10 years"
3.last-modified/if-modified-since
有些資料隨時都在變化。cnn.com 的主頁經常幾分鐘就更新。另一方面,google.com 的主頁幾個星期才更新一次 (當他們上傳特殊的假日 logo,或為乙個新服務作廣告時)。 web 服務是不變的:通常伺服器知道你所請求的資料的最後修改時間,並且 http 為伺服器提供了一種將最近修改資料連同你請求的資料一同傳送的方法。
所有現代的瀏覽器都支援最近修改 (last-modified) 的資料檢查。如果你曾經訪問過某頁,一天後重新訪問相同的頁時發現它沒有變化,並奇怪第二次訪問時頁面載入得如此之快——這就是原因所在。你的瀏覽器首次訪問時會在本地快取頁面內容,當你第二次訪問,瀏覽器自動傳送首次訪問時從伺服器獲得的最近修改日期。伺服器簡單地返回 304: not modified (沒有修改),因此瀏覽器就會知道從本地快取載入頁面。在這一點上,web 服務也如此智慧型。
4. etag/if-none-match這幾個http頭可以作為meta標籤傳送到客戶端,但是需要注意的是http頭中的設定優先順序更高一些,例如:
總結expires/cache-control header是控制瀏覽器是否直接從瀏覽器緩訪問資料還是重新發請求到伺服器取資料。只是cache-control比expires可以控制的多一些,而且cache-control會重寫expires的規則。
last-modified/if-modified-since和etag/if-none-match是瀏覽器傳送請求到伺服器後判斷檔案是否已經修改過,如果沒有修改過就只傳送乙個304回給瀏覽器,告訴瀏覽器直接從自己本地的緩訪問資料;如果修改過那就整個資料重新發給瀏覽器。
客戶端瀏覽器的快取問題排查
最近對檔案上傳功能進行了優化改版,上線之後有同事反饋出來,自從上線之後所上傳的,均沒有設定瀏覽器端快取,導致客戶端每次都要去請求伺服器上的資源,會導致頁面載入速度變慢,使用者體驗不好諸類問題。之前從未接觸過此類問題趕忙查閱了瀏覽器快取的相關知識,並對問題進行了修復,現將一些所學進行整理歸納。在chr...
客戶端封裝瀏覽器
官網訪問位址 開發時用sdk,開啟的客戶端頁面可以f12檢視頁面資訊 上線時用下面那個。安裝好後的資料夾 vue專案打包,npm run build,生成乙個static資料夾和乙個index.html,index.html就是入口頁面 現在需要建立乙個配置檔案package.json webkit...
HTTP快取機制 客戶端快取
http快取機制分為兩種,客戶端快取和服務端快取,本文主要對客戶端快取進行簡單的分析。服務端快取又分為 伺服器快取 和 反向 伺服器快取 也叫閘道器快取,比如 nginx反向 squid等 其實廣泛使用的 cdn 也是一種服務端快取,目的都是讓使用者的請求走 捷徑 並且都是快取 檔案等靜態資源。客戶...