本文對一次完整的請求和渲染過程作了一個詳細的總結,小夥伴若是以爲本文對你稍微有所幫助的話,能夠給筆者點個贊,有疑問的地方歡迎私聊。css
DNS
解析域名獲取IP
地址http
請求(TCP三次握手
)html
文件渲染頁面TCP四次揮手
)說到這裏就不得不提一下
DNS
這哥們的解析順序了html
瀏覽器緩存
IP
映射,未找到則進行下一步查找。系統緩存
host
文件中查找是否存在該域名對應的IP
映射。路由器緩存
IP
映射。ISP(互聯網服務提供商) DNS緩存
ISP DNS緩存
中查找。就好比你用的網絡是聯通的,那就進入聯通的DNS緩存服務器
中查找。根域名服務器
.com
)的IP
地址發送給客戶端。主域名服務器
DNS服務器
向根域名服務器返回的主域名服務器發起請求,主域名服務器收到請求後,查詢本身緩存,若沒有則返回本身下一級域名服務器IP
地址,若仍是未找到,就重複該步驟直到找到該域名對應的IP
地中。保存當前結果到緩存,並返回給客戶端
IP地址
請求對應資源。強緩存經過返回頭的
cache-control
、expires
判斷前端
對比緩存經過首部的
ETag
、last-modified
判斷web
Expires是一個絕對時間,即服務器時間。瀏覽器檢查當前時間,若是還沒到失效時間就直接使用緩存文件。可是該方法存在一個問題:服務器時間與客戶端時間可能不一致。所以該字段已經不多使用。瀏覽器
cache-control中的max-age保存一個相對時間。例如Cache-Control: max-age = 484200,表示瀏覽器收到文件後,緩存在484200s內均有效。 若是同時存在cache-control和Expires,瀏覽器老是優先使用cache-control。緩存
指令 | 參數 | 說明 |
---|---|---|
private | 無 | 代表響應只能被單個用戶緩存,不能做爲共享緩存(即代理服務器不能緩存它) |
public | 可省略 | 代表響應能夠被任何對象(包括:發送請求的客戶端,代理服務器,等等)緩存 |
no-cache | 可省略 | 緩存前必需確認其有效性 |
no-store | 無 | 不緩存請求或響應的任何內容 |
max-age=(s) | 必須 | 響應的最大值 |
Pragma
Pragma
是HTTP/1.1
以前版本遺留的通用首部字段,僅做爲於HTTP/1.0
的向後兼容而使用。雖然它是一個通用首部,可是它在響應報文中時的行爲沒有規範,依賴於瀏覽器的實現。RFC
中該字段只有no-cache
一個可選值,會通知瀏覽器不直接使用緩存,要求向服務器發請求校驗新鮮度。由於它優先級最高,當存在時必定不會命中強緩存。服務器
若是響應報文首部的
expires
的時間大於請求的時間或者max-age
不爲0而且cache-control
設置的值不爲no-cache
或者no-store
,同時請求報文首部不存在Pragma
字段的時候纔會命中強緩存。網絡
last-modified
是第一次請求資源時,服務器返回的字段,表示最後一次更新的時間。下一次瀏覽器請求資源時就發送if-modified-since
字段。服務器用本地Last-modified
時間與if-modified-since
時間比較,若是不一致則認爲緩存已過時並返回新資源給瀏覽器;若是時間一致則發送304
狀態碼,讓瀏覽器繼續使用緩存。Etag
:資源的實體標識(哈希字符串),當資源內容更新時,Etag
會改變。服務器會判斷Etag
是否發生變化,若是變化則返回新資源,不然返回304。由上圖咱們能夠清晰的看到TCP
三次握手的詳細過程。dom
SYN
置爲1(表示要創建鏈接),生成一個隨機數seq=x
,進入SYN_SEND
狀態ack=x+1
,將SYN
置爲1,ACK
置爲1,也生成一個隨機數seq=y
,進入SYN_RECV
;ACK=y+1
,服務器接收到確認包,鏈接創建成功,客戶端和服務器進入ESTABLISHED
狀態。服務器接收到客戶端的http
請求後會將該http
請求封裝成一個Request
對象,並經過不一樣的web
服務器處理,處理完結果以Response
對象返回給客戶端,主要內容爲狀態碼
、請求頭
、響應報文
三個部分。async
狀態碼 | 類別 | 緣由短語 |
---|---|---|
1xx | Informational(信息性狀態碼) | 接受的請求正在處理 |
2xx | Success(成功狀態碼) | 請求正常處理完畢 |
3xx | Redirection(重定向狀態碼) | 須要進行附加操做以完成請求 |
4xx | Client Error(客戶端錯誤狀態碼) | 服務器沒法處理請求 |
5xx | Server Error(服務器錯誤狀態碼 | 服務器處理請求出錯 |
HTML
文件,生成DOM
樹CSS
文件,生成CSS
樹DOM
樹和CSS
樹,生成渲染樹瀏覽器解析HTML
文件自上而下解析遇到CSS
文件會阻塞頁面渲染和JS
文件的執行,CSS
文件不會阻塞js
文件加載,他們是能夠並行的,若是js
文件具備defer
(IE)或者async
屬性時,該js
文件加載完就當即執行,不會受到css
加載的影響。
一旦頁面
DOM
樹生成接解析完畢就會觸發DOMContentLoaded
(PS:IE用onreadystatechange
),就能夠經過document.addEventListener('DOMContentLoaded',callback,false)
來進行綁定監聽事件。
概念
Reflow
,又叫layout
,通常意味着DOM
元素內容、結構、位置或尺寸發生變化,須要從新計算樣式和渲染樹,這個過程叫作迴流。
Repaint
,通常是由於元素一些外觀上的改變(例如:背景色,邊框顏色,字體顏色等),此時只要應用新樣式繪製到元素上就好了,這個過程叫重繪。
因此迴流比重繪的代價高的多得多,每一個節點都有reflow
方法,一個節點產生迴流,可能會致使子元素產生迴流,甚至會致使父節點或者兄弟節點產生迴流。
觸發迴流的一些操做
DOM
節點會觸發Repaint
和Reflow
CSS
一些樣式(如:改變節點尺寸等)js
獲取精確CSS
樣式的時候(如:getComputedStyle
,scroll
家族,offset
家族,client
家族等,使用這些方法將強制刷新隊列)會產生上面的問題的根源仍是現代瀏覽器都比較聰明,他們經過隊列化修改並批量執行來優化重排的過程,瀏覽器會將修改操做都放入一個隊列當中,等到過了一段時間或者達到一個閾值纔會清空隊列。
那麼咱們爲了減小回流優化頁面性能又該採起什麼樣的措施呢?
display:none
,修改完以後再讓他顯示,這樣只會觸發兩次重排DocumentFragment
來進行批量操做後再插回頁面position:absolute(fixed)
cssText
。將須要操做的樣式一次性合併而後做用到元素上。咱們說了這麼多的減小重繪、重排,好像還忘了一個神奇的東西。bingo
,就是咱們的CSS3 GPU加速
啦!
能觸發GPU硬件加速的有以下幾個屬性:
transform
filter
opacity
Wall-change
他們的優勢在於,在使用transform filter opacity
屬性實現動畫時,不會觸發重排和重繪;固然,在享受GPU硬件加速帶來的好處的同時呢,咱們也得考慮一個問題就是若是太多元素使用這個特性,將會出現內存內存佔用過大,影響性能。
FIN
表明斷開鏈接標誌位,ACK
確認標誌位,seq
隨機數,這裏筆者就很少說了,相似於前面所述的三次握手
FIN=1
+seq=u
標誌位ACK=1
,其中ack=u+1
,seq=v
FIN=1
+seq=w
+ACK=1
+ack=u+1
ACK=1
,ack=w+1
,seq=w+1
到這裏一次完整的TCP
四次揮手就完結了,你們看完這個可能會有疑問,爲何是四次揮手而不是三次,爲何FIN
和ACK
並非一塊兒發送的,那麼這裏筆者就得說道說道了。
由於剛開始是客戶端主動請求斷開鏈接,這僅僅表示客戶端沒有數據傳給服務端了,並不表明服務端的數據也傳輸完了,發送一個ACK
確認標誌位只是告訴客戶端我知道了。
等到服務端數據也傳輸完了,纔會出現第三次握手,也就是服務端主動發送一個FIN+ACK
給客戶端,告訴客戶端個人數據也發送完了,咱們分手吧,而後客戶端收到了,再告訴服務端我知道了。至此,分手完畢。
筆者一次性巴拉巴拉這麼多,可能你們會有點很差消化,但是筆者的初衷仍是但願可以遇到一個知識點就解決它並延申一些相關知識點,這樣比零散的查找會好得多。
參考文章