說來慚愧,做爲一名前端開發,只知道http緩存機制的存在,它能夠優化http性能,可是http緩存究竟是個啥,它是怎麼工做的,那就不知道了css
一般來講,咱們在瀏覽器中打開一個頁面,須要向服務器發送請求,請求css,圖片,js等動態資源,這些靜態資源修改的少,通常客戶端會把它們存儲起來,當客戶端再次請求時,能夠從本地緩存中直接讀取,這樣能夠減小http請求,給服務器減負,html
http緩存的優點就體現出來啦!Http 緩存機制做爲 web 性能優化的重要手段,要想了解Http 緩存機制,得先弄清楚http的傳輸前端
一.http的傳輸web
HTTP想要發送一條報文的時候,須要通過如下兩個步驟:segmentfault
使用TCP做爲傳輸層:瀏覽器
一個HTTP請求過程以下圖所示:緩存
針對以上圖示,咱們解答幾個常見的問題:性能優化
a. 瀏覽器在發起請求時首先會作什麼?答,查找本地緩存服務器
根據URL查找本地緩存啦!先看本地緩存中是否有當前請求的URL的內容,若是存在,固然好了,直接用就行了。若是不存在,那就得去向服務器請求該URL了。併發
首先讓咱們回顧一下瀏覽器的緩存標識字段都有哪些:
Cache-control,指明當前資源的有效期,控制瀏覽器是否直接從瀏覽器緩存取數據仍是從新發請求到服務器取數據。
Expires,Web服務器響應消息頭字段,在響應http請求時告訴瀏覽器在過時時間前瀏覽器能夠直接從瀏覽器緩存取數據,而無需再次請求。Expires是HTTP1.0的東西,因此它的做用咱們能夠基本忽略了。
Last-Modified,標示請求資源的最後修改時間。
Etag,web服務器響應請求時,告訴瀏覽器當前資源在服務器的惟一標識。
這麼多緩存標識,判斷時確定得有個優先級吧,那是確定的,Cache-control優先級高於Expires,Etag優先級高於Last-Modified。說這麼多,直接上圖吧,看下圖更清晰:
b. 瀏覽器查找完緩存以後接下來要作的是什麼呢?答,DNS query
首先客戶機將域名查詢請求發送到本地DNS服務器,本地DNS服務器先在以前的記錄(緩存)中查找,若是有緩存,則直接利用緩存進行解析,若是沒有緩存,則進入本地的緩存的尋找。若是本地服務器不能在本地找到緩存,則將請求發送到根域名DNS服務器。
DNS服務器在拿到咱們的域名後,會將它解析成IP地址返回給瀏覽器,這樣瀏覽器就能直接定位到要請求的服務器的地址了。
c. 找到服務器地址以後確定就是向服務器發送請求,創建鏈接,這個不用問了。
這樣根據IP和端口,瀏覽器就開始跟服務器創建TCP鏈接啦。看到TCP鏈接,咱們就想到了三次握手。
TCP是面向鏈接的,不管哪一方向另外一方發送數據以前,都必須先在雙方之間創建一條鏈接。在TCP/IP協議中,TCP協議提供可靠的鏈接服務,鏈接是經過三次握手進行初始化的。三次握手的目的是同步鏈接雙方的序列號和確認號並交換 TCP窗口大小信息。
第一次握手:創建鏈接。客戶端發送鏈接請求報文段,將SYN位置爲1,Sequence Number爲x;而後,客戶端進入SYN_SEND狀態,等待服務器的確認;
第二次握手:服務器收到SYN報文段。服務器收到客戶端的SYN報文段,須要對這個SYN報文段進行確認,設置Acknowledgment Number爲x+1(Sequence Number+1);同時,本身本身還要發送SYN請求信息,將SYN位置爲1,Sequence Number爲y;服務器端將上述全部信息放到一個報文段(即SYN+ACK報文段)中,一併發送給客戶端,此時服務器進入SYN_RECV狀態;
第三次握手:客戶端收到服務器的SYN+ACK報文段。而後將Acknowledgment Number設置爲y+1,向服務器發送ACK報文段,這個報文段發送完畢之後,客戶端和服務器端都進入ESTABLISHED狀態,完成TCP三次握手。
完成了三次握手,客戶端和服務器端就能夠開始傳送數據。
d. 瀏覽器在接收到服務器返回的數據後會怎麼作呢?答,解析數據,生成渲染樹
渲染展示頁面是確定的啦,關鍵是如何渲染。咱們先來看一下瀏覽器的簡單處理步驟:
(1)解析HTML/SVG/XHTML,build DOM樹。
(2)解析CSS,build CSSOM樹。
(3)build render樹。render樹並不等同於DOM樹,由於一些像Header或display:none的東西就不必放在render樹中了。
(4)reflow。計算每一個Element在設備中顯示的具體位置。
(5)paint。最後經過調用操做系統Native GUI的API繪製。
二.緩存規則解析
HTTP緩存有多種規則,根據是否須要從新向服務器發起請求來分類,我將其分爲兩大類(強制緩存,對比緩存)
在詳細介紹這兩種規則以前,先經過時序圖的方式,讓你們對這兩種規則有個簡單瞭解。
已存在緩存數據時,僅基於強制緩存,請求數據的流程以下:
已存在緩存數據時,僅基於對比緩存,請求數據的流程以下:
咱們能夠看到兩類緩存規則的不一樣,強制緩存若是生效,不須要再和服務器發生交互,而對比緩存不論是否生效,都須要與服務端發生交互。
兩類緩存規則能夠同時存在,強制緩存優先級高於對比緩存,也就是說,當執行強制緩存的規則時,若是緩存生效,直接使用緩存,再也不執行對比緩存規則。
三.用戶行爲與緩存
a. 瀏覽器url回車、頁面連接跳轉、新開窗口、前進、後退
瀏覽器發現緩存中有這個文件,就不發送任何請求了,直接去緩存中獲取展示。(最快)
b. 按下F5刷新
F5就是告訴瀏覽器,別偷懶,好歹去服務器看看這個文件是否有過時了。因而瀏覽器就膽膽襟襟的發送一個請求帶上If-Modify-since。
而後服務器發現:誒,這個文件我在這個時間後還沒修改過,不須要給你任何信息了,返回304就好了。因而瀏覽器獲取到304後就去緩存中歡歡喜喜獲取資源了。
c. 按下Ctrl+F5
這個但是要命了,告訴瀏覽器,你先把你緩存中的這個文件給我刪了,而後再去服務器請求個完整的資源文件下來。因而客戶端就完成了強行更新的操做。
參考連接: