回爐計劃第三篇,這是一個經典的前端面試題,考察範圍很是的廣,可深刻的角度也很是的多。本篇文章的目的主要是回顧,因此內容和網絡上流傳的文章會有必定的重疊性。css
過程大體分爲如下幾個步驟html
DNS 服務和 HTTP 協議同樣,都是位於應用層的協議,它提供域名到 ip 地址之間的解析服務。 以查詢www.baidu.com
的 ip 地址爲例前端
補充:域名和 url 是兩個概念,域名是用來確認服務器的地址的,而 url 是用來確認資源的地址;域名和 ip 地址不是一一對應的,一個域名同一時刻只能解析出一個 ip 地址,而一個 ip 地址能夠綁定多個域名html5
這就涉及到著名的 http 三次握手。簡單來講與服務器創建鏈接須要經歷如下三個過程。web
syn
包(syn=j
)到服務器,並進入 SYN_SEND 狀態,等待服務器確認;syn
包,必須確認客戶的 syn
(ack=j+1
),同時本身也發送一個 SYN
包(syn=k
),即 SYN+ACK
包,此時服務器進入 SYN_RECV
狀態;SYN+ACK
包,向服務器發送確認包 ACK
(ack=k+1
),此包發送完畢,客戶端和服務器進入 ESTABLISHED
狀態,完成三次握手。這裏能夠延申拓展一下 HTTPS 的知識 HTTPS 詳解--segmentfault面試
這一步主要是後端從接口獲取到 tcp 報文,處理以後返回HTTP Request
對象,也就是響應報文。編程
HTTP 響應報文也是由三部分組成: 狀態碼, 響應報頭和響應報文。segmentfault
狀態碼由三位數字組成,表示響應的類型。狀態碼有五大類 1xx,2xx,3xx,4xx,5xx後端
響應報頭 HTTP 請求頭提供了關於請求,響應或者其餘的發送實體的信息。 HTTP 響應頭信息-菜鳥編程
響應報文:就是服務器返回給瀏覽器的文本信息了,包括 html,js,css 等資源
瀏覽器拿到響應報文以後,開始解析報文並呈現網頁。因爲不一樣的瀏覽器引擎實現的方法可能不一致,咱們以webkit
內核爲例進行說明。 WebKit 渲染的過程大體分爲四步 瀏覽器的工做原理:新式網絡瀏覽器幕後揭祕
構建 dom 樹 -> 構建 render 樹 -> 佈局 render 樹 -> 繪製 render 樹
呈現引擎將開始解析 HTML 文檔,並將各標記逐個轉化成「內容樹」上的 DOM 節點。同時也會解析外部 CSS 文件以及樣式元素中的樣式數據。HTML 中這些帶有視覺指令的樣式信息將用於建立另外一個樹結構:呈現樹。
呈現樹包含多個帶有視覺屬性(如顏色和尺寸)的矩形。這些矩形的排列順序就是它們將在屏幕上顯示的順序。
呈現樹構建完畢以後,進入「佈局」處理階段,也就是爲每一個節點分配一個應出如今屏幕上的確切座標。下一個階段是繪製 - 呈現引擎會遍歷呈現樹,由用戶界面後端層將每一個節點繪製出來。
須要着重指出的是,這是一個漸進的過程。爲達到更好的用戶體驗,呈現引擎會力求儘快將內容顯示在屏幕上。它沒必要等到整個 HTML 文檔解析完畢以後,就會開始構建呈現樹和設置佈局。在不斷接收和處理來自網絡的其他內容的同時,呈現引擎會將部份內容解析並顯示出來。
上面說到: 瀏覽器是一個邊解析邊渲染的過程。這個過程就涉及到兩個比較重要的概念:重繪(repain)和迴流(reflow)。
當頁面中元素樣式的改變並不影響它在文檔流中的位置時(例如:color
、background-color
、visibility
等),瀏覽器會將新樣式賦予給元素並從新繪製它,這個過程稱爲重繪。
當Render Tree
中部分或所有元素的尺寸、結構、或某些屬性發生改變時,瀏覽器從新渲染部分或所有文檔的過程稱爲迴流。
會致使迴流的操做
會致使迴流的屬性和方法
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
scrollIntoView()
、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
頁面在首次加載的時候一定會經歷reflow
和repain
。reflow
和 repain
過程是很是消耗性能的,尤爲是在移動設備上,它會破壞用戶體驗,有時會形成頁面卡頓。因此咱們應該儘量少的減小 reflow
和 repain
。
TCP 的鏈接的拆除須要發送四個包,所以稱爲四次揮手(Four-way handshake),也叫作改進的三次握手。客戶端或服務器都可主動發起揮手動做,在 socket 編程中,任何一方執行 close() 操做便可產生揮手操做。
假設客戶端想要關閉鏈接,客戶端發送一個 FIN 標誌位置爲 1 的包,表示本身已經沒有數據能夠發送了,可是仍然能夠接受數據。
發送完畢後,客戶端進入 FIN_WAIT_1 狀態。
服務器端確認客戶端的 FIN 包,發送一個確認包,代表本身接受到了客戶端關閉鏈接的請求,但尚未準備好關閉鏈接。
發送完畢後,服務器端進入 CLOSE_WAIT 狀態,客戶端接收到這個確認包以後,進入 FIN_WAIT_2 狀態,等待服務器端關閉鏈接。
服務器端準備好關閉鏈接時,向客戶端發送結束鏈接請求,FIN 置爲 1。
發送完畢後,服務器端進入 LAST_ACK 狀態,等待來自客戶端的最後一個 ACK。
客戶端接收到來自服務器端的關閉請求,發送一個確認包,並進入 TIME_WAIT 狀態,等待可能出現的要求重傳的 ACK 包。
服務器端接收到這個確認包以後,關閉鏈接,進入 CLOSED 狀態。
客戶端等待了某個固定時間(兩個最大段生命週期,2MSL,2 Maximum Segment Lifetime)以後,沒有收到服務器端的 ACK ,認爲服務器端已經正常關閉鏈接,因而本身也關閉鏈接,進入 CLOSED 狀態。
【問題 1】爲何鏈接的時候是三次握手,關閉的時候倒是四次握手? 答:由於當 Server 端收到 Client 端的 SYN 鏈接請求報文後,能夠直接發送 SYN+ACK 報文。其中 ACK 報文是用來應答的,SYN 報文是用來同步的。可是關閉鏈接時,當 Server 端收到 FIN 報文時,極可能並不會當即關閉 SOCKET,因此只能先回復一個 ACK 報文,告訴 Client 端,"你發的 FIN 報文我收到了"。只有等到我 Server 端全部的報文都發送完了,我才能發送 FIN 報文,所以不能一塊兒發送。故須要四步握手。
【問題 2】爲何 TIME_WAIT 狀態須要通過 2MSL(最大報文段生存時間)才能返回到 CLOSE 狀態?
答:雖然按道理,四個報文都發送完畢,咱們能夠直接進入 CLOSE 狀態了,可是咱們必須假象網絡是不可靠的,有能夠最後一個 ACK 丟失。因此 TIME_WAIT 狀態就是用來重發可能丟失的 ACK 報文。