先進行 URL
解析,看看輸入的內容是否符合 URL
規則(解析 URL
提取出協議、域名、端口號,對於一些特殊字符,在傳遞的時候須要進行編碼解碼)。css
encodeURI
、decodeURI
能夠對中文、空格等編碼解碼,適用於 URL
自己encodeURIComponent
、decodeURIComponent
範圍更廣,會編碼解碼一些特殊字符如 :/?=+@#$
,適用於給參數編碼解碼URL
符合規則,瀏覽器進程會經過進程通訊將 URL
請求發送給網絡進程,網絡進程會依次查找 Memory Cache
、Disk Cache
中是否有緩存內容,有且沒過時則使用,不然則發送網絡請求。html
網絡請求第一步就是先進行 DNS
解析,獲取請求域名服務器的 IP
地址。前端
什麼是
DNS
解析,每臺計算機都有一個惟一IP
地址,可是IP
地址不方便記憶,因此採用更方便記憶的網址去查找其餘計算機,將網址轉換成IP
地址的過程就是DNS
解析。webpack
域名解析是一個遞歸查詢 + 迭代查詢的過程。git
host
文件中查找ISP
互聯網服務提供商緩存,好比 114.114.114.114
,DNS
服務器進行迭代查詢:.
根 DNS
服務器 -> .com
頂級服務器 -> 主域名服務器 -> ...,直到服務器返回對應的 IP
DNS
負載均衡:github
網站對應的
IP
不止一個,DNS
能夠根據每臺機器的負載量、距離用戶的距離等返回一個合適的服務器IP
給用戶,這個過程就是DNS
負載均衡,又叫作DNS
重定向。CDN
就是利用DNS
的重定向技術,DNS
會返回一個用戶最接近的點的IP
給用戶。web
拿到 IP
後,(檢查當前域名是否達到 TCP
鏈接上限),經過三次握手進行 TCP
鏈接面試
三次握手:算法
SYN
包和初始序號 seq = x
給服務端,此時客戶端狀態爲 SYN-SENT
SYN
包後,將標識位 SYN
和 ACK
置爲1,確認序號 ack = x + 1
, 初始序號 seq = y
發送給客戶端,此時服務端狀態爲 SYN-RECEIVED
ACK
置爲1, 確認序號 ack = y + 1
, 本身的序號 seq = x + 1
, 發送給服務端,服務端收到後也將狀態切換爲 ESTABLISHED
三次握手抽象版:瀏覽器
seq
序號,用來標識從TCP
源端向目的端發送的字節流,發起方發送數據時對此進行標記ack
確認序號,只有ACK
標誌位爲1時,確認序號字段纔有效,ack=seq+1
標識位:
ACK
:確認標識,用於表示對數據包的成功接收。SYN
:同步標識,表示 TCP
鏈接已初始化,發起一個新鏈接。FIN
:完成標識,釋放一個鏈接,用於拆除上一個 SYN
標識。一個完整的TCP鏈接過程必定會有 SYN
和 FIN
包。爲何不能兩次握手?
TCP
的特色的可靠傳輸,服務端和客戶端都須要可靠傳輸,就須要確認雙方的發送和接收能力,第一次握手確認了客戶端的發送能力,第二次確認了服務端的發送和接收能力,第三次確認了客戶端的接收能力
兩次握手,服務器不能肯定客戶端已經收到了確認請求,不能確認是否創建好了鏈接。服務器認爲創建好了鏈接,發送數據包,結果發的包客戶端沒收到,那麼攻擊服務器就很容易了,只發包不收包。
TCP
和 UDP
的區別:
TCP
是一個面向鏈接的、可靠的、基於字節流的傳輸層協議,TCP
會精準記錄哪些數據發送了,哪些數據被對方接收了,哪些沒有被接收到,並且保證數據包按序到達,不容許半點差錯。這是有狀態
, 當意識到丟包了或者網絡環境不佳,TCP
會根據具體狀況調整本身的行爲,控制本身的發送速度或者重發。這是可控制
。UDP
是一個面向無鏈接的傳輸層協議,無狀態
、不可控
。TCP 鏈接創建以後,瀏覽器端會構建請求行、 請求頭等信息,並把和該域名相關的 Cookie 等數據附加到請求頭中,而後向服務器發送構建的請求信息。若是是 HTTPS
,還須要進行 TSL
協商。
服務器檢查 HTTP
請求頭是否包含緩存驗證信息進行協商緩存
:
Last-Modified
和 If-Modified-Since
:
Last_Modified
表示本地文件的最後修改時間,If-Modified-Since
會將Last-Modified
的值發送給服務器詢問該資源是否有更新,若是有更新就會將新的資源發送回來,不然返回304
狀態碼,表明資源無更新,繼續使用緩存文件。
Last-Modified
弊端:
Last-Modified
修改,服務器不能命中緩存。Last-Modified
的值並不會修改,會返回304
,瀏覽器就會是本身的緩存 。ETag
和 If-No-Match
ETag
是文件指紋,If-No-Match
會將ETag
發送給服務器,查詢該資源ETag
是否變更,有變更的話就將新的資源發送回來。ETag
優先級高於Last-Modified
。
若是什麼緩存都沒設置,瀏覽器一般會響應頭中的 Date
減去 Last-Modified
值的 10% 做爲緩存時間。
狀態碼用於表示服務器對請求的處理結果
1xx
:指示信息——表示請求已經接受,繼續處理
100 Continue
通常在發送 post
請求時,已發送了 http header
以後服務端返回此信息,表示確認,以後發送具體參數信息。2xx
:成功
200 OK
正常返回信息201 Created
請求成功而且服務器建立了新的資源202 Accepted
服務器已接受請求,但還沒有處理3xx
:重定向
301 Moved Permanently
永久重定向302 Found
臨時重定向303 See Other
臨時重定向,且老是使用 GET
請求新的 URI
304 Not Modified
請求內容未改動,走緩存4xx
:客戶端錯誤
400 Bad Request
服務器沒法理解請求格式401 Unauthorized
請求未受權403 Forbidden
禁止訪問404 Not Found
找不到與 URI
相匹配的資源5xx
:服務器錯誤。
500 Internal Server Error
服務器內部錯誤503 Service Unavailable
服務器暫時沒法處理請求數據傳輸完後,若是請求頭或響應頭裏沒有 connection: keep-alive
,則須要四次揮手斷開 TCP
鏈接,不然會保持鏈接通道,這樣下一次在發送請求,就無需再次TCP三次握手了,節省了網絡通訊時間。
http1.0
中默認Connection
並非keep-alive
,須要手動處理,可是HTTP1.1
以後,Connection:keep-alive
已經被列入了規範,如今基本都是默認就是長鏈接,前提是同一個源,向不一樣源發送請求要從新創建通道。
四次揮手:
FIN
,用來關閉客戶端到服務端的數據傳輸,告訴服務端我不會給你發送數據了FIN
包後,發送一個 ACK
給客戶端,確認序號爲收到序號 + 1FIN
,用來關閉服務端到客戶端的數據傳輸,告訴客戶端我不會給你發數據了FIN
後,發送一個 ACK
給服務端,確認序號爲收到序號 + 1,完成四次揮手四次揮手抽象版:
四次握手後,客戶端還會等待 2MSL
(MSL:最長報文段壽命,通常2min) 的時間,爲了保證客戶端發送的 ACK
報文可以到達服務器,由於這個報文可能會丟失,服務器收不到確認會超時重傳 FIN
+ ACK
報文段,客戶端能在 2MSL
時間內收到這個重傳的報文段,而後客戶端從新確認。
爲何鏈接的時候是三次握手,關閉的時候倒是四次揮手?
SYN
鏈接請求報文後,能夠直接發送 SYN + ACK
報文FIN
報文時,極可能並不會當即關閉鏈接,因此只能先回復一個 ACk
報文,告訴客戶端你發的 FIN
報文我收到了,只有等服務端全部的報文發送完了,我才能發送 FIN
報文,所以不能一塊兒發送,因此須要四次。gzip
壓縮後的文件則進行解壓縮,若是響應頭 Content-type
爲 text/html
,則開始解析 HTML
HTML Parser
對 HTML
文件進行處理,根據 HTML
標記關係構建 DOM
樹。 - 解析過程當中遇到圖片、link
、script
會啓動下載。 - script
標籤會阻塞 DOM
樹的構建,因此通常將 script
放在底部,或者添加 async
、defer
標識。 - css
下載時異步,不會阻塞瀏覽器構建 DOM
樹,可是會阻塞渲染,在構建佈局樹時,會等待 css
下載解析完畢後才進行。
CSS
樣式錶轉化爲瀏覽器能夠理解的 styleSheets
,轉換樣式表中的屬性使其標準化em => px; bold => 700
。DOM
樹和 styleSheets
構建佈局樹,計算出元素的佈局信息,display: none
不可見節點以及 head
這種不可見標籤不會插入到佈局樹裏
DOM
樹、構建 CSSOM
樹、構建樹並非嚴格的前後順序,爲了讓用戶能儘快看到網頁內容,都是並行推動的position: fixed/absolute
、z-index:2
、filter: blue(5px)
、opacity: .5
等擁有層疊上下文屬性的元素會進行分層、或者內容須要裁減GPU
加速生成,渲染進程把生成圖塊的指令發送給 GPU
進程,GPU
生成最終的位圖並保存在內存之中優化
CSS
下載到客戶端,充分利用 HTTP
多請求併發機制,且 CSS
下載並不會阻塞渲染,style、link、@import
放到頁面頂部JS
加載阻塞渲染,添加 async、defer
標識,標籤放到頁面底部DOM
的迴流和重繪
async
和defer
都是異步的,使用async
標誌的腳本文件一旦加載完成,會當即執行;而使用了defer
標記的腳本文件,須要在DOMContentLoaded
事件以前執行。
重繪:元素樣式的改變,可是寬高、大小、位置等不變,好比:
color
、background
、visibility
等
迴流:元素的大小或者位置發送了變化,觸發了頁面的從新佈局,甚至調用方法或屬性
getComputedStyle
、clientWidth
,爲了保證獲得的結果是即便性
和準確性
,致使佈局樹從新計算佈局和渲染。
優化策略:
table
佈局,由於一個小改動可能會形成整個 table
的從新佈局documentFragment
操做 dom
,操做完成後再添加到文檔中position
屬性爲 absolute
、fixed
元素上,脫離文檔流,單獨渲染區域CSS3
硬件加速, transform
、opacity
等屬性會觸發 GPU
加速,不會引起迴流和重繪,可是過多使用可能會佔用大量內存,性能消耗嚴重flush
隊列,而後一次性清空。DNS
預解析CDN
,DNS
負載均衡<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//g.alicdn.com" />
複製代碼
web
服務器、資源服務器、數據服務器,增長 HTTP
併發性TCP
的三次握手和四次揮手:HTTP1.1默認開啓的 Connection: keep-alive
webpack
對傳輸內容進行壓縮GZIP
壓縮,通常能壓縮 60%
左右HTTP
請求的次數base64
,可是可能會形成圖片大小增長 1/3
HTTP1.1
雖然在串行請求能夠經過 Connection: keep-alive
複用同一個 TCP
鏈接,若是是並行發送多個請求,會創建多個鏈接,可是瀏覽器通常限制會限制同一域名下最多同時能夠創建6個鏈接。
TCP
發出下一個請求,因此會受到前面請求的阻塞。多路複用:容許同時經過單一的 HTTP2.0
鏈接發起的多重請求 - 響應消息,鏈接通道是共享的
HTTP2.0
的傳輸是基於二進制幀的,每一個 TCP
鏈接中,都有多個雙向流通的流,每一個流都有獨一無二的標識和優先級,而流就是由二進制幀組成的。二進制幀會標識本身是屬於哪一個流的,因此這些流能夠交錯傳輸,在接收端根據幀頭組裝成完整的信息,解決線頭堵塞的問題。
頭部壓縮:HTTP1.x
的 header
中帶有大量的信息,每次都要重複發送,HTTP2.0
使用 HPACK
算法對 header
數據進行壓縮,減小須要傳輸的 header
大小,通信雙方各自緩存一個頭部字典表,能夠差別化更新頭部,減小須要傳輸數據的大小