從輸入URL到看到頁面,究竟發生了什麼?這個問題需要分為兩個部分來回答。1:HTTP請求 2:浏覽器渲染
1、首先是HTTP請求:
發起HTTP請求之前,先确認請求内容是否有本地緩存。
提到HTTP,與之密不可分的就是TCP/IP協定族。TCP/IP分為四個層級:應用層(HTTP)--傳輸層(TCP)--網絡層(IP)--鍊路層。
1.1 HTTP、DNS、SSL
如果輸入的URL是一個域名,則需要通過DNS協定解析成IP位址。
HTTP協定生成針對目标位址的請求封包。
請求封包包括的主要字段有:請求類型(比如get post 前者主要用于獲得請求主體内容 後者主要用于傳輸主體内容 其他的比如PUT/DELETE 上傳/删除檔案 HEAD隻傳回相 應頭) uri http版本 請求首(頭) 正文(主體)
管線化連結:http1.1提出的持久連結(connection:keep-alive)
SSL:對于HTTPS的請求,會先通過SSL協定(公鑰私鑰方法以及混合加密)建立加密的通信管道,之後再進行正常的http請求,此外SSL可校驗伺服器證書,可校驗内容的完整性。
HTTPS=HTTP+加密通信+證書驗證+内容完整校驗
1.2 TCP
TCP将HTTP協定生成的請求封包進行分割,标記序列号以及端口号後轉發給網絡層
TCP協定會通過三次握手政策,確定雙方的通信正常。發送方發送一個SYN(可以了解為請求同步标志)給對方。接收方接收後傳回SYN(請求同步) & ACK(确認同步),請求 方收到接收方新的SYN後再次回複ACK以及資料包,三次握手結束
此過程一旦終端,會重新開始
1.3 IP(internet protocol)
接受TCP過來的資料,并添加通信目标位址後交給鍊路層
能夠傳達目的地,需要IP協定明确對方IP位址和MAC位址(MAC位址可以是對方的主機MAC位址也可以是中間中轉點的MAC位址,如果是經過MAC中轉,MAC搜尋下一個MAC的過程将會使用ARP協定解析位址)。
1.4鍊路層
就是實體傳輸層,比如網路,路由等
1.5 接受端--鍊路層--IP層--TCP層--HTTP層
與發出的順序相反,來解析接收的請求,并給出響應。
如果接收方是代理伺服器,則首先判斷有沒有代理緩存,沒有會請求最終伺服器。有就直接傳回(最終伺服器可以通過cache-control控制緩存與否)
出于安全,引入了cookie,可以根據cookie判斷會話狀态(服務端會校驗請求帶來的cookie的有效期、域、協定等資訊)。
1.6 響應狀态
響應可以為0:比如跨域的情況
2XX:請求是沒問題的,也正常傳回。但傳回結果視情況而定
3XX:伺服器需要經過處理才能正常傳回,如果資源已經更新而請求的還是老内容,或者不符合請求頭中的條件
4XX:服務端無法了解等因為用戶端原因導緻的失敗
5XX:服務端出錯導緻失敗
2、浏覽器渲染
當成功從伺服器傳回内容後,就會進行渲染。
2.1 DOM樹 樣式 渲染樹 渲染
浏覽器解析HTML成DOM樹。樹的每個節點對應一個HTML元素。
解析樣式,會對應到DOM樹中的每個節點。
渲染樹類似于添加了樣式的DOM樹,但是渲染樹不含隐藏的元素
完成渲染樹後,渲染頁面。
2.2 渲染阻塞
按序加載可以導緻阻塞,此處不詳述。
JS通常因為單線程原因導緻渲染阻塞。但其實js單線程而浏覽器不是單線程。浏覽器除了有JS線程還有渲染線程此外還有定時器線程等。
渲染線程和JS線程雖然獨立,但是JS依然能夠阻塞渲染線程。這主要是因為:如果渲染線程準備給DOM1渲染為紅色,在渲染過程中,如果JS線程可以同步執行,而又JS又在操作DOM1的顔色為藍色,此時就會發生一些沖突。為了避免這樣的事情發生,是以JS線程在執行的時候,渲染線程會被臨時挂起。這也導緻了,JS可能引起渲染阻塞。