瀏覽器快取(brower caching)是瀏覽器在本地磁碟對使用者最近請求過的文件進行儲存,當訪問者再次訪問同一頁面時,瀏覽器就可以直接從本地磁碟載入文件。
我們可以通過chrome://view-http-cache/來檢視chrome瀏覽器快取了什麼內容。
推薦閱讀文章:大公司裡怎樣開發和部署前端**?
注意,一般,我們快取的都是css、js、之類的檔案,這些檔案的改動比較小,而html檔案是不快取的,因為html檔案中常常包含動態的內容,比如引入a.css?v=1.0,最後是版本號,如果html也被快取,那麼我們就沒辦法達到通過修改版本號進而使得使用者獲取新內容的目的了。
快取型別分為強快取和協商快取。
強快取:在使用者請求資源時,如果命中強快取,則不向伺服器請求,而直接從本地獲取資源。我們可以看到200狀態碼,並提示from disk cache或from memory cache(區別後面講)。
協商快取: 在使用者請求資源時,瀏覽器直接則向伺服器傳送請求,伺服器根據 request header 來判斷是否命中協商快取,如果命中,則返回304和新的response header,使用本地資源;否則,返回新的資源。
強快取和協商快取的共同點:兩者命中後都是從本地讀取資源。
強快取和協商快取的區別: 強快取很強勢,是沒有向伺服器發出請求的; 而協商快取必須要向伺服器發乙個請求來協商。
強快取是利用http的響應頭中的expires欄位和cache-control兩個欄位來控制的,用來表示使用快取的有效時間。
expires是http1.0規範的,表示快取的過期時間。 如某個資源的response heade中的字段: expires: fri, 18 aug 2017 07:57:17 gmt。 表示當瀏覽器再次載入這個資源時,如果時間沒有超過,就命中強快取,使用記憶體中快取的資源。
之所以瀏覽器在再次載入時可以判斷出時間是否超過,是因為瀏覽器在快取資源時,不僅快取了資源,還快取了response header相關的內容,比如這裡expires欄位。缺點:由於不能保證伺服器和使用者端的絕對時間保持一致,所以快取有時可能會出現混亂的情況, 在http1.1版本中開始使用cache-control的方法進行快取。
cache-control是http1.1規範的,同樣表示快取的過期時間。 其中的max-age是作為判斷是否過期的主要判據,它是乙個相對時間,單位為s。 如知乎上的某一張的response header中的字段:cache-control: public, max-age=31536000。 public代表了這張是可以被任何使用者快取的,包括**伺服器等; 而max-age是表示在31536000s(一年)內,如果再次請求就使用本地資源。
cache-control除了max-age的使用之外,還有幾個比較重要的字段:
相同點: 兩者都是強快取。
不同點:
協商快取一般是使用if-modified-since/last-modified和if-none-match/etag 由伺服器來決定瀏覽器快取的資源是否可以使用。
在使用者請求到資源之後,會返回這個資源,並且在response header中返回乙個 last-modifed 字段,這時瀏覽器就會快取這個資源以及最後的修改時間, 可以是: last-modified: fri, 18 aug 2017 07:27:24 gmt。 接著,當使用者再次請求相同的資源時,需要在請求頭中新增 if-modified-since 字段,這個欄位的值就是之前儲存的 last-modifed 的值,伺服器得到 if-modified 值之後,會和資源最近的修改時間作比較,如果命中,則返回304,讓瀏覽器使用快取的資源;否則,返回乙個最新的資源並且在 last-modified 修改為最近的資源修改時間。
在使用者請求到資源之後,會返回這個資源,並且在response heade 中返回乙個 etag 字段,即 entity tag,這個欄位的值是乙個字串,唯一的標識了這個資源,只要資源發生了變化,這個etag值就會發生變化。當使用者再次請求資源時,會在request header中攜帶 if-none-match 字段,其值為上次快取的 etag 值,如果命中,則返回304,使用快取資源;否則,伺服器返回最新的資源。
相同點: 都是為了協商快取。
不同點:
下一次載入時,首先比較cache-control,如果沒有超過時間,則命中強快取,不傳送請求,直接讀取本地檔案(如果不支援http1.1,則使用expires來判斷);如果時間已經過期,則傳送帶有if-none-match和if-modified-since的請求頭。
伺服器接受到請求之後,首先判斷etag是否和伺服器上檔案的etag一致,如果一致,則命中協商快取,返回304;如果不一致,返回新的資源並帶上新的etag值返回200。
如果請求中沒有etag值,則比較傳送來的 if-modified-since 值,如果命中,則返回304,;否則,返回新的資源帶上新的last-modified的值並返回狀態碼200。
f5重新整理,瀏覽器會設定max-age=0,跳過強快取判斷,進行協商快取判斷;
ctrl+f5重新整理,跳過強快取和協商快取,直接從伺服器拉取資源。
優點:
這是最省資源的方式,瀏覽器甚至都不需要發起請求。
缺點:快取脫離控制,如果快取時間太長,使用者無法訪問最新的頁面,特別是出現乙個緊急的bug的時候,需要一段時間,才能平息。
使用:在header頭部新增expires、cache-control、max-age、last-modified、etag的乙個或者是多個,可以在meta中對快取進行控制。
建議:js、css、可以把快取時間設定的久一些,永遠不過期都是可以的,檔案出現變化的時候,通過更換(新增)版本號就行更新。
根據智慧型dns解析,使用者訪問到最近的一台機器,這樣就可以減少網路延遲。
使用者訪問cdn,cdn上如果資源存在並且沒有過期,直接返回給使用者內容,否則需要先訪問源站,然後儲存到cdn伺服器上面,然後返回使用者。
優點:
(1)請求分散,削弱了高流量下的壓力。
(2)減少了網路延遲。
缺點:
(1)節點資源可能快取不一致,導致不同的使用者看到的結果不同。
(2)如果設定過期時間短或者其他的不合理的回源策略(即又訪問源伺服器),會導致大量回源,導致訪問速度變慢。
(3)高併發期間,乙個資源,可能會有多個回源請求。
(4)重新整理cdn,需要一段時間, 如果出現bug, 也得登上幾分鐘。
很多**伺服器都支援了快取,比如nginx,apache。一些動態頁面或者介面不怎麼更新,比如產品列表等,可以把內容快取到伺服器裡面,下次請求的時候,直接讀取快取,動態指令碼都不需要執行。動態指令碼如果要返回的話,可能需要訪問資料庫,以及一些其他的服務,這就增加了相應時間。
使用:nginx,可以配置 proxy_cache
apache,可以配置 mod_cache、mod_disk_cache、mod_file_cache以及mod_mem_cache
是針對php**。php執行的時候,需要先對php**解釋,生成中間**,稱為opcode,然後再執行。如果快取住,就可以不需要每一次都解釋,這樣就可以節省不少資源,增加吞吐量。
優點:節省資源,增加吞吐量。
缺點:(1)**更新,需要等待opcode失效,如果設定不過期,那就需要重啟伺服器。
(2)opcode主要節省了cpu和記憶體資源,如果時間消耗主要是磁碟或者是網路io,那麼作用不是太大。
會把計算或者從資料庫,以及其他服務獲得資料,放到乙個檔案裡面,使用的時候取出來。常見的session就是這麼做的。我看phpcms就大量使用這種快取。
缺點:1)多台伺服器,資料快取內容可能不一致。為了解決這個問題,曾經掛載共享**,這就導致磁碟io成為瓶頸。
2)設定過期時間,不太容易。
瀏覽器快取機制小結
web效能優化措施中,合理設定瀏覽器快取是重要的優化手段之一,它可以加快頁面訪問速度和節省使用者網路頻寬等。簡單介紹下相關概念。expires出自http1.0,cache control出自http1.1,同時設定兩者時,cache control 會覆蓋 expires。expires指定的是實...
瀏覽器快取小結
因為最近面試經常會被問到304快取的問題,因此在網上蒐集了各種資料,小記一下 快取有瀏覽器快取,伺服器快取,服務端快取等,這裡著重記一下瀏覽器快取 瀏覽器第一次像伺服器發起請求時,如果有快取,瀏覽器在返回資訊裡面會帶上相應的快取策略,下面介紹一下有哪些常用的快取策略。expires 過期時間,這是h...
瀏覽器快取機制
最近在準備優化日誌請求時遇到了一些令人疑惑的問題,比如為什麼響應頭里出現了兩個 cache control 為什麼明明設定了 no cache 卻還是發請求,為什麼多次訪問時有時請求裡帶了 etag,有時又沒有帶?等等。後來查了一些資料以及同事親自驗證,總算對這些問題有了個清晰的理解,現在整理出來以...