從輸入URL到頁面顯示
當輸入URL、敲下回車、最後瀏覽器頁面顯示,這裡面有什麼故事?鍵盤到作業系統、作業系統到瀏覽器、瀏覽器到伺服器、伺服器返回資料頁面渲染……
鍵盤到作業系統
回車鍵按下時,與鍵盤相關的電路閉合,通過消抖操作,鍵盤的電路系統將回車鍵轉化為鍵碼13。按鍵被按下會觸發中斷事件,回車鍵的鍵碼被編碼並通過通用序列匯流排(USB)傳輸到中斷請求線上(IRQ),中斷控制器接收到IRQ上的訊號後,會對映一箇中斷向量。中斷描述符表將中斷向量對映到對應的處理函式上(中斷處理器)。
作業系統到瀏覽器
作業系統通過相應的API函式獲取到當前的活動視窗(該瀏覽器)並獲取到當前瀏覽器位址列控制代碼,作業系統使用sendMessage
sendMessage
函式引數將帶有按鍵以及按鍵的資訊。然後瀏覽器位址列控制代碼的訊息處理函式將被呼叫,處理訊息佇列中的訊息。
瀏覽器到伺服器
處理URL
關鍵字or地址:瀏覽器搜先分析位址列的內容是關鍵字還是URL。若位址列的為關鍵字,則使用瀏覽器的搜尋引擎搜尋該關鍵字。當把文字作為關鍵字傳遞給搜尋引擎時,通常會在URL後面加上一個引數,這個引數告訴搜尋引擎搜尋來自哪個瀏覽器。
HSTS列表: HSTS強制客戶端使用HTTPS與伺服器建立連線。若訪問的URL在HSTS列表裡,則瀏覽器會把HTTP協議變為HTTPS。
編碼:
DNS查詢
瀏覽器處理完URL後,將獲取要訪問的URL所在伺服器的地址。這時需要進行DNS查詢。
DNS查詢過程:
- 查詢本地DNS快取
- 檢視本地host表
- 查詢DNS伺服器
在DNS伺服器上進行查詢時,首先查詢本地DNS伺服器。若本地DNS
伺服器上有域名的快取,則本地DNS伺服器將對應IP傳送給查詢方。若本地DNS伺服器上沒有域名的快取,則向根域名伺服器發起查詢(遞迴)。根域名伺服器收到請求後,會返回下一級域名資訊的DNS伺服器地址。本地DNS伺服器收到地址後繼續進行查詢(迭代),最後獲取到目標域名的IP併發送給查詢方。
TCP連線
此時獲取到URL中域名的IP地址,通過協議可以獲取到埠(HTTP:80、HTTPS:443),下一步該進行瀏覽器與伺服器之間的連線。
瀏覽器使用socket函式來進行TCP連線,初始化socket時引數為 AF_INET
和SOCK_STREAM
。
TCP建立連線過程(三次握手):
- 客戶端傳送一個TCP包。設定SYN=1(請求建立連線)、Seq=X(隨機產生的序列號)
- 伺服器發回確認包(ACK)應答。SYN=1、ACK=1、ACK number = X+1、Seq = Y(隨機產生)
- 客戶端再次傳送確認包(ACK) 。SYN=0、ACK=1、ACK number= Y+1、Seq = X+1
TCP斷開連線過程(四次揮手):
- 客戶機給伺服器一個FIN為1的TCP報文
- 伺服器返回給客戶端一個確認ACK報文
- 伺服器給客戶端傳送一個FIN報文
- 客戶機回覆ACK報文
伺服器動作
從瀏覽器發起請求到請求到頁面資料的過程中,可能會經過負載均衡等中間部分
負載均衡
方式 | 說明 | 特點 |
---|---|---|
HTTP重定向 | 瀏覽器向web伺服器請求某個URL後,web伺服器可以通過http響應頭資訊中的Location標記來返回一個新的URL | 主站點伺服器的吞吐率平均分配到了被轉移的伺服器;重定向的伺服器工作量不同,實際的負載量不可估計 |
DNS負載均衡 | 在DNS伺服器中配置多個A記錄,將這些A記錄對應的伺服器構造成叢集,,例如CDN | 可以根據使用者IP選擇最近的伺服器,無法記錄HTTP請求上下文 |
反向代理 | 轉發http請求(應用層),常用nginx | 所有HTTP請求都必須經過代理,可以為不同的實際伺服器設定不同的權重,要求併發處理能力要求高,可以可以監控後端伺服器 |
IP負載均衡 | 網路層通過修改請求目標地址進行負載均衡(網路層) | 吞吐率高,要求網路頻寬大 |
請求處理
- 伺服器收到請求後將請求解析為:請求方法、域名、請求路徑
- 伺服器找到該域名對應的虛擬主機,並驗證該虛擬主機是否可以使用該請求方法
- 伺服器獲取請求路徑對應的內容,並根據內容使用指定的程式來處理(e.g.使用不同的程式解析PHP、JSP等檔案),將輸出的結果傳送給瀏覽器
PLUS - 請求方法
方法 | 描述 |
---|---|
GET |
請求指定的頁面資訊,並返回實體主體。 |
POST |
向指定資源提交資料進行處理請求(例如提交表單或者上傳檔案) |
PUT |
從客戶端向伺服器傳送的資料取代指定的文件的內容 |
HEAD |
與get類似,不過返回的響應中沒有具體的內容,用於獲取報頭 |
DELETE |
請求伺服器刪除指定的頁面 |
OPTIONS |
返回伺服器針對特定資源所支援的HTTP請求方法 |
TRACE |
回顯伺服器收到的請求,主要用於測試或診斷 |
CONNECT |
HTTP/1.1協議中預留給能夠將連線改為管道方式的代理伺服器 |
瀏覽器頁面渲染
瀏覽器收到伺服器返回的頁面資料後,開始對頁面進行渲染
瀏覽器程序與執行緒
瀏覽器是多程序的,用於頁面顯示的有Browser程序、第三方外掛程序、GPU程序(3D繪製等)、瀏覽器渲染程序(瀏覽器核心,每個Tab頁面都有一個渲染程序)。
瀏覽器渲染程序包含的執行緒:
- GUI渲染執行緒
- JS引擎執行緒
- 事件觸發執行緒
- 定時器觸發器執行緒
- 非同步http請求執行緒
注意: JavaScript可以操作DOM,如果修改元素的時候同時渲染頁面,就可能出現不可預料的結果,所以GUI渲染執行緒與JS引擎執行緒是互斥的
瀏覽器渲染頁面過程
- 解析HTML建立dom樹
- 解析css構建render樹(將CSS程式碼解析成樹形的資料結構,然後結合DOM合併成render樹)
- 佈局render樹(確定每個節點在螢幕上的位置)
- 繪製render樹(遍歷render樹,並使用UI後端層繪製每個節點)
CSS載入是否會阻塞dom樹渲染?
- css載入不會阻塞DOM樹解析
- css載入會阻塞render樹渲染
迴流和重繪
- 迴流:瀏覽器重新渲染部分或全部文件的過程
- 重繪:元素改變的樣式不影響元素位置時,瀏覽器將新樣式賦予給元素並重新繪製它的過程