DNS查詢順序如下,若其中一步成功則直接跳到建立鏈接部分:
瀏覽器自身DNS
操作系統DNS
本地hosts文件
向域名服務器發送請求
TCP三次握手(three-way handshaking)
發送方:SYN(synchronize)
接收方:SYN/ACK(acknowledgement),確認信息傳達
發送方:ACK - 確認接收方在線可收消息,握手結束
Accept
TCP三次握手的的好處在於:發送方可以確認接收方仍然在線,不會因爲白髮送而浪費資源。
報文首部(GET /index.html HTTP/1.1)
方法
URL
HTTP版本
空行(CR+LF)
報文主體
注意:1.HTTP是無連接
、無狀態
的,即HTTP在傳輸完成後就會斷開(HTTP1.1以前),並且不會記錄訪問者的狀態。
從HTTP/1.1開始才支持持久連接,即通信一次以後連接不中斷。
正常來說,HTTP請求、響應方式爲每請求一次就響應一次:
請求1 -> 響應1 -> 請求2 -> 響應2 -> 請求3 -> 響應3
若採用持久連接請求管線化方式:
請求1 -> 請求2 -> 請求3 -> 響應1 -> 響應2 -> 響應3
使用管線化的條件:
服務端需要支持管線化
只有GET和HEAD可以進行管線化,POST請求有所限制
管線化不會影響響應到來的順序
2.關於CR(Carriage Return,回車)和LF(Line Feed,換行)
Dos和Windows採用CR/LF表示下一行UNIX/Linux採用LF表示下一行MAC OS系統則採用CR表示下一行
報文首部(HTTP/1.1 200 OK)
HTTP版本
響應狀態碼
狀態碼信息
空行(CR+LF)
報文主體
執行以下過程:
根據DOCTYPE來確定文檔類型(最常見的就是HTML5,注意如果是HTML4的話有嚴格和寬鬆模式之分)
構建DOM樹(根據HTML構建類似於二叉樹的結構樹)
下載資源
CSS - 構建CSSOM樹
js - 一般下載後立即執行,會阻塞頁面渲染
在聊瀏覽器渲染之前,我們先明確一個概念: 事實上,我們看到的頁面並不是直觀所見的一層圖頁,而是由許多DOM元素渲染層(Layers)組成的,如下圖。
所以一個的頁面的渲染過程由如下幾步構成:
佈局(layout): CPU根據渲染樹佈局計算元素的具體位置和大小,轉換成絕對像素,並且根據樣式,分割成多個獨立的渲染層(Layers),將每一層對應到位圖中
繪製(Paint): GPU根據每個渲染層(Layers)的位圖繪製每個點,即像素填充,並且將所以渲染層緩存,如果下次頁面變動但是渲染層沒變就不會觸發重繪。
層級合成(Compositing): 顧名思義,即處理多層渲染層之間的關係,將其合成爲一個完整的頁面。
重繪(repaint)
:
元素視覺表現屬性被改變即觸發重繪,如改變visibility,color等,不會影響到dom結構
reflow(重排)
:
與repaint區別就是:所有影響dom的元素佈局的事件都會觸發重排。同時也會觸發repaint。
這種開銷是非常昂貴的,導致性能下降是必然的,頁面元素越多效果越明顯。
reflow
常見情況:
增刪改DOM節點
移動DOM的位置或是動畫顯示(所以儘量用canvas來做動畫)
修改width、display等CSS樣式
resize窗口或是滾動的時候
修改網頁默認字體(不建議)
display:none會觸發reflow和repaint,而visibility:hidden只會產生repaint
壓縮DOM深度,以免內層元素改變而導致多個外層都改變。
對於沒用的元素,儘量設置爲display:none
,減輕繪製壓力。
在對DOM進行大量元素操作時,我們可以使用利用DocumentFragment對象進行操作,最後再一次性裝載進DOM結構中。
指定img的大小:由於img是內聯元素,所以在加載後會改變寬高,嚴重的會導致整個頁面重排,所以最好在渲染前就設置好其寬高,或者讓其脫離文檔流。
知道了瀏覽器頁面的渲染合成過程後,我們不難得出一個結論:
如果我們把會發生大量重繪重排的元素提取出來,單獨觸發一個渲染層(Layer),就不會把其他元素一起帶着重繪,這會大大提高頁面性能。
那麼如何觸發渲染層,讓GPU來加速繪製呢?最簡單的方法有以下三種:
will-change: transform;will-change: opacity;transform: translateZ(0);
PS:使用Layers來觸發GPU加速(硬件加速)也會帶來負面影響,如電量損失過快、佔用內存和GPU等。所以在使用中要注意不能濫用,在常觸發重繪和重排的元素上使用即可。