從輸入URL到頁面呈現知識點詳解

狀態碼

本文對一次完整的請求和渲染過程作了一個詳細的總結,小夥伴若是以爲本文對你稍微有所幫助的話,能夠給筆者點個贊,有疑問的地方歡迎私聊。css

概述

  • DNS解析域名獲取IP地址
  • 發起http請求(TCP三次握手)
  • 服務器處理請求,並返回請求資源
  • 瀏覽器解析html文件渲染頁面
  • 關閉請求(TCP四次揮手)

DNS 解析

說到這裏就不得不提一下DNS這哥們的解析順序了html

  • 瀏覽器緩存
    • 若是有解析這個域名的記錄,而且沒有清除瀏覽器緩存就存在該域名的IP映射,未找到則進行下一步查找。
  • 系統緩存
    • 從本機host文件中查找是否存在該域名對應的IP映射。
  • 路由器緩存
    • 從路由器緩存記錄中查找是否存在該域名的解析記錄,有則返回對應的IP映射。
  • ISP(互聯網服務提供商) DNS緩存
    • 以上三種方式屬於本地查詢,若是仍是未找到則進入ISP DNS緩存中查找。就好比你用的網絡是聯通的,那就進入聯通的DNS緩存服務器中查找。
  • 根域名服務器
    • 全球僅存在13臺根域名服務器,1臺主根域名服務器,12臺輔根域名服務器。以上方式都未成功,則進入根域名服務器,根域名服務器收到請求後會查詢區域文件記錄,若不存在則將其管轄範圍下的主域名服務器(如.com)的IP地址發送給客戶端。
  • 主域名服務器
    • 本地DNS服務器向根域名服務器返回的主域名服務器發起請求,主域名服務器收到請求後,查詢本身緩存,若沒有則返回本身下一級域名服務器IP地址,若仍是未找到,就重複該步驟直到找到該域名對應的IP地中。
  • 保存當前結果到緩存,並返回給客戶端
    • 客戶端拿到IP地址請求對應資源。

緩存

強緩存經過返回頭的cache-controlexpires判斷前端

對比緩存經過首部的ETaglast-modified判斷web

強緩存

  • Expires是一個絕對時間,即服務器時間。瀏覽器檢查當前時間,若是還沒到失效時間就直接使用緩存文件。可是該方法存在一個問題:服務器時間與客戶端時間可能不一致。所以該字段已經不多使用。瀏覽器

  • cache-control中的max-age保存一個相對時間。例如Cache-Control: max-age = 484200,表示瀏覽器收到文件後,緩存在484200s內均有效。 若是同時存在cache-control和Expires,瀏覽器老是優先使用cache-control。緩存

指令 參數 說明
private 代表響應只能被單個用戶緩存,不能做爲共享緩存(即代理服務器不能緩存它)
public 可省略 代表響應能夠被任何對象(包括:發送請求的客戶端,代理服務器,等等)緩存
no-cache 可省略 緩存前必需確認其有效性
no-store 不緩存請求或響應的任何內容
max-age=(s) 必須 響應的最大值
  • Pragma

PragmaHTTP/1.1以前版本遺留的通用首部字段,僅做爲於HTTP/1.0的向後兼容而使用。雖然它是一個通用首部,可是它在響應報文中時的行爲沒有規範,依賴於瀏覽器的實現。RFC中該字段只有no-cache一個可選值,會通知瀏覽器不直接使用緩存,要求向服務器發請求校驗新鮮度。由於它優先級最高,當存在時必定不會命中強緩存。服務器

若是響應報文首部的expires的時間大於請求的時間或者max-age不爲0而且cache-control設置的值不爲no-cache或者no-store,同時請求報文首部不存在Pragma字段的時候纔會命中強緩存。網絡

對比緩存

  • last-modified是第一次請求資源時,服務器返回的字段,表示最後一次更新的時間。下一次瀏覽器請求資源時就發送if-modified-since字段。服務器用本地Last-modified時間與if-modified-since時間比較,若是不一致則認爲緩存已過時並返回新資源給瀏覽器;若是時間一致則發送304狀態碼,讓瀏覽器繼續使用緩存。
  • Etag:資源的實體標識(哈希字符串),當資源內容更新時,Etag會改變。服務器會判斷Etag是否發生變化,若是變化則返回新資源,不然返回304。

圖解緩存

TCP三次握手

TCP三次握手圖解

由上圖咱們能夠清晰的看到TCP三次握手的詳細過程。dom

  • 首先是由客戶端發送一個創建鏈接的請求,SYN置爲1(表示要創建鏈接),生成一個隨機數seq=x,進入SYN_SEND狀態
  • 服務端接收到請求,首選確認ack=x+1,將SYN置爲1,ACK置爲1,也生成一個隨機數seq=y,進入SYN_RECV
  • 客戶端收到請求後,發送確認包ACK=y+1,服務器接收到確認包,鏈接創建成功,客戶端和服務器進入ESTABLISHED狀態。

服務器接收到客戶端的http請求後會將該http請求封裝成一個Request對象,並經過不一樣的web服務器處理,處理完結果以Response對象返回給客戶端,主要內容爲狀態碼請求頭響應報文三個部分。async

常見狀態碼

狀態碼 類別 緣由短語
1xx Informational(信息性狀態碼) 接受的請求正在處理
2xx Success(成功狀態碼) 請求正常處理完畢
3xx Redirection(重定向狀態碼) 須要進行附加操做以完成請求
4xx Client Error(客戶端錯誤狀態碼) 服務器沒法處理請求
5xx Server Error(服務器錯誤狀態碼 服務器處理請求出錯

頁面渲染

domTree

cssTree

基本流程

  • 解析HTML文件,生成DOM
  • 解析CSS文件,生成CSS
  • 合併DOM樹和CSS樹,生成渲染樹
  • 佈局和繪製頁面(迴流,重繪)

瀏覽器解析HTML文件自上而下解析遇到CSS文件會阻塞頁面渲染和JS文件的執行,CSS文件不會阻塞js文件加載,他們是能夠並行的,若是js文件具備defer(IE)或者async屬性時,該js文件加載完就當即執行,不會受到css加載的影響。

一旦頁面DOM樹生成接解析完畢就會觸發DOMContentLoadedPS:IE用onreadystatechange),就能夠經過document.addEventListener('DOMContentLoaded',callback,false)來進行綁定監聽事件。

迴流和重繪

概念

  • 迴流

Reflow,又叫layout,通常意味着DOM元素內容、結構、位置或尺寸發生變化,須要從新計算樣式和渲染樹,這個過程叫作迴流。

  • 重繪

Repaint,通常是由於元素一些外觀上的改變(例如:背景色,邊框顏色,字體顏色等),此時只要應用新樣式繪製到元素上就好了,這個過程叫重繪。

因此迴流比重繪的代價高的多得多,每一個節點都有reflow方法,一個節點產生迴流,可能會致使子元素產生迴流,甚至會致使父節點或者兄弟節點產生迴流。

觸發迴流的一些操做

  • 刪除、新增DOM節點會觸發RepaintReflow
  • 操做節點位置改變或給節點添加一個動畫
  • 改變CSS一些樣式(如:改變節點尺寸等)
  • 窗口大小改變
  • 修改網頁默認字體
  • 網頁初始化的時候
  • js獲取精確CSS樣式的時候(如:getComputedStylescroll家族,offset家族,client家族等,使用這些方法將強制刷新隊列)

會產生上面的問題的根源仍是現代瀏覽器都比較聰明,他們經過隊列化修改並批量執行來優化重排的過程,瀏覽器會將修改操做都放入一個隊列當中,等到過了一段時間或者達到一個閾值纔會清空隊列。

那麼咱們爲了減小回流優化頁面性能又該採起什麼樣的措施呢?

  • 在須要對一個節點採用數次操做時能夠先將該元素display:none,修改完以後再讓他顯示,這樣只會觸發兩次重排
  • 須要使用js操做多個節點時能夠借用DocumentFragment來進行批量操做後再插回頁面
  • 讓須要被操做的節點先脫離標準文檔流
    • position:absolute(fixed)
    • 浮動
  • 使用cssText。將須要操做的樣式一次性合併而後做用到元素上。

咱們說了這麼多的減小重繪、重排,好像還忘了一個神奇的東西。bingo,就是咱們的CSS3 GPU加速啦!

CSS3 GPU加速

能觸發GPU硬件加速的有以下幾個屬性:

  • transform
  • filter
  • opacity
  • Wall-change

他們的優勢在於,在使用transform filter opacity屬性實現動畫時,不會觸發重排和重繪;固然,在享受GPU硬件加速帶來的好處的同時呢,咱們也得考慮一個問題就是若是太多元素使用這個特性,將會出現內存內存佔用過大,影響性能。

TCP四次揮手

TCP四次揮手

FIN表明斷開鏈接標誌位,ACK確認標誌位,seq隨機數,這裏筆者就很少說了,相似於前面所述的三次握手

  • 首先客戶端向服務器端發送一個FIN=1+seq=u標誌位
  • 服務端收到請求發送一個確認號ACK=1,其中ack=u+1,seq=v
  • 以後服務器再次向客戶端發送一個FIN=1+seq=w+ACK=1+ack=u+1
  • 客戶端收到後,向服務端發送一個ACK=1,ack=w+1,seq=w+1

到這裏一次完整的TCP四次揮手就完結了,你們看完這個可能會有疑問,爲何是四次揮手而不是三次,爲何FINACK並非一塊兒發送的,那麼這裏筆者就得說道說道了。

由於剛開始是客戶端主動請求斷開鏈接,這僅僅表示客戶端沒有數據傳給服務端了,並不表明服務端的數據也傳輸完了,發送一個ACK確認標誌位只是告訴客戶端我知道了。

等到服務端數據也傳輸完了,纔會出現第三次握手,也就是服務端主動發送一個FIN+ACK給客戶端,告訴客戶端個人數據也發送完了,咱們分手吧,而後客戶端收到了,再告訴服務端我知道了。至此,分手完畢。

筆者一次性巴拉巴拉這麼多,可能你們會有點很差消化,但是筆者的初衷仍是但願可以遇到一個知識點就解決它並延申一些相關知識點,這樣比零散的查找會好得多。

參考文章

瀏覽器HTTP緩存機制

從輸入url到頁面加載完成發生了什麼?——前端角度

你真的瞭解迴流和重繪嗎?

相關文章
相關標籤/搜索