天天看點

從浏覽器位址欄輸入url到顯示頁面的過程

基本流程:

1、使用者在浏覽器中輸入url位址

2、浏覽器解析域名得到伺服器ip位址

浏覽器會首先從緩存中找是否存在域名,如果存在就直接取出對應的ip位址,

如果沒有就開啟一個DNS域名解析器。

DNS域名解析器會首先通路頂級域名伺服器,将對應的ip發給用戶端;

然後通路根域名解析器,将對應的ip發給用戶端;

最後通路本地域名伺服器,得到最終的ip位址。

3、TCP三向交握建立用戶端和伺服器的連接配接

因為HTTP是基于TCP的可靠傳輸,是以在發送http資料報之前,

需要先進行TCP的三次握手建立連接配接。三次握手過程如下:

第一次握手:用戶端--->服務端 ack=1,seq=x(x随機生成)

第二次握手:服務端--->用戶端 ACK=1,ack=x+1,seq=y(y随機生成)

第三次握手:用戶端--->服務端 ACK=1,ack=y+1,seq=x+1

完成第三次握手時,實際上用戶端已經與伺服器建立了連接配接,

是以第三次握手的封包已經可以攜帶資料了。

4、用戶端發送HTTP請求擷取伺服器端的靜态資源

5、伺服器發送HTTP響應封包給用戶端,用戶端擷取到頁面靜态資源

6、TCP四次揮手關閉用戶端和伺服器的連接配接

資料傳輸完畢後,TCP會進行四次揮手斷開連接配接,釋放資源。四次揮手過程如下:

第一次揮手:用戶端--->伺服器 FIN=1,ack=1,seq=u 用戶端狀态變為FIN_WAIT_1

第二次揮手:伺服器--->用戶端 ACK=1,ack=u+1,seq=v 伺服器狀态變為CLOSE_WAIT,TCP進入半關閉狀态

第三次揮手:伺服器--->用戶端 FIN=1,ACK=1,ack=u+1,seq=w 伺服器狀态變為LAST_ACK

第四次揮手:用戶端--->伺服器 ACK=1,ack=w+1,seq=u+1 用戶端狀态變為TIME_WAIT,

此時TCP未釋放,需要等待計時器計時完成後,用戶端狀态變為CLOSED

7、浏覽器解析文檔資源并渲染頁面

浏覽器解析文檔資源并渲染頁面流程:

(1)解析html資源,建構DOM Tree

(2)解析css資源,建構CSS Rule Tree

(3)JS通過DOM API和CSS OM API來操作DOM Tree和CSS Tree

(4)解析完成後綜合DOM Tree和CSS Tree會生成Render Tree,

         計算每個元素的位置,這個過程就是回流(layout or reflow)

(5)調用作業系統Native GUI的繪制

(6)頁面繪制完成

涉及到的其他知識點:

1、Render Tree的生成

DOM Tree和CSS Tree結合會生成Render Tree,是由可視化元素按照其順序生成的樹形結構,非可視化元素是不會出現到渲染樹中的。

非可視化元素:head、display:none;(注意:visibility:hidden的元素會出現在渲染樹中)

2、回流和重繪

回流(reflow,也叫重排、布局):某部分的變化影響了布局,浏覽器需要重新渲染。(如元素大小、位置的改變)

重繪(repaint):元素的某一部分發生改變,尺寸、位置沒有改變。(字型顔色、背景顔色的改變)

引起回流的幾個主要原因:

(1)網頁初始化

(2)JS操作DOM樹(增加、删除元素等)

(3)某些元素的尺寸改變

(4)CSS屬性的改變

浏覽器的“dirty”系統:

為了避免頁面細小的改變就引起回流和重繪,

“dirty”系統會将這些改變操作積攢一批再進行操作,這又叫異步reflow或者增量異步reflow。有些特殊情況不會這麼做:resize視窗、改變了頁面預設的字型等,

這些操作會直接觸發回流。

編寫代碼時如何減少回流和重繪:

(1)修改樣式不要逐條修改,定義CSS樣式的class,直接修改元素的className

(2)不要将DOM節點的屬性值放在循環中當成循環的變量

(3)為動畫的HTML元素使用fixed或absolute的position屬性,修改它們的CSS就不會觸發reflow

(4)把DOM離線後修改,設定display:none或者clone元素到記憶體中,修改完成再顯示回頁面

(5)不要使用table布局,一個微小的改變就可能引起整個table的重新布局

3、性能優化

(1)提升HTML的加載速度

頁面精簡,删除不必要的内容,将内嵌的JS和CSS移至外部檔案,使用壓縮工具等

減少檔案數量,合并檔案,減少請求次數

減少域名查詢,外部引入的資源盡量少使用不同的域名

使用緩存,重用資料

優化頁面元素的加載順序

使用合法的标簽

根據浏覽器類型選擇合适的政策

(2)編寫合理的CSS

DOM的深度盡量淺

使用合法的CSS屬性

不要為ID選擇器指定類名或标簽名

避免使用後代選擇器,盡量使用子選擇器

避免使用通配符

(3)關于JS标簽

js标簽的加載和執行特點:載入後立即執行,執行時會阻塞頁面後續内容

将所有的js标簽放在頁面底部,保證腳本執行前已完成DOM渲染

盡可能合并腳本

減少内聯js的使用

注意多個js标簽的引入順序

使用defer屬性,該屬性可以使腳本在文檔完全呈現以後再執行

使用async屬性,可以使目前腳本不必等待其他腳本的執行,也不必阻塞文檔的呈現