導航會發生什麼事
這是 4 篇網誌系列的第 2 集,介紹 Chrome 內部的運作方式。 在前一篇文章中,我們探討了不同的程序和執行緒如何處理瀏覽器的不同部分。在本文中,我們會深入探究每個程序和執行緒的通訊方式,以便顯示網站。
讓我們看看簡單的網路瀏覽用途:您在瀏覽器中輸入網址,接著瀏覽器會從網際網路擷取資料並顯示網頁。在這篇文章中,我們會著重在使用者要求網站 和瀏覽器準備為網頁轉譯前 (也稱為導覽) 的部分。
首先是瀏覽器程序
如第 1 部分:CPU、GPU、記憶體和多程序架構所述,分頁外的所有內容都會由瀏覽器程序處理。瀏覽器程序包含可繪製按鈕和輸入欄位的執行緒,例如用於繪製按鈕和輸入欄位的網路執行緒;網路執行緒負責處理網路堆疊接收網際網路資料,以及控制檔案存取權的儲存空間執行緒等。當您在網址列中輸入網址時,瀏覽器程序的 UI 執行緒會處理輸入內容。
簡易導覽
步驟 1:處理輸入資料
當使用者開始在網址列中輸入內容時,UI 執行緒首先會詢問「這是一項搜尋查詢還是網址?」。在 Chrome 中,網址列也是搜尋輸入欄位,因此 UI 執行緒需要進行剖析,並決定是否將您傳送到搜尋引擎或您要求的網站。
步驟 2:開始導航
當使用者按下進入時,UI 執行緒會發出網路呼叫,以取得網站內容。載入旋轉圖示會顯示在分頁的角落,而網路執行緒會通過適當的通訊協定,例如 DNS 查詢並為該要求建立 TLS 連線。
此時,網路執行緒可能會收到伺服器重新導向標頭,例如 HTTP 301。在這種情況下,網路執行緒會與伺服器要求重新導向的 UI 執行緒進行通訊。接著,系統會發出另一個網址要求。
步驟 3:朗讀回覆
回應主體 (酬載) 開始進入後,網路執行緒會視需要查看串流的前幾個位元組。回應的 Content-Type 標頭應會顯示資料類型,但因為內容可能遺漏或錯誤,所以這裡會執行「MIME 類型探測」。這是在原始碼中加註的「虛構商家」。 您可以閱讀註解,瞭解不同瀏覽器如何處理 content-type/payload 組合。
如果回應是 HTML 檔案,下一步就是將資料傳遞至轉譯器程序。如果是 ZIP 檔案或其他檔案,表示這是下載要求,因此需要將資料傳送給下載管理員。
系統也會執行SafeBrowsing檢查。如果網域和回應資料似乎與已知的惡意網站相符,網路執行緒快訊就會顯示警告頁面。此外,系統也會進行 Cross Origin Read Blocking (CORB) 檢查,以確保轉譯器程序不會接觸到敏感的跨網站資料。
步驟 4:尋找轉譯器程序
完成所有檢查,且網路執行緒確定瀏覽器應前往要求的網站後,網路執行緒會告知 UI 執行緒資料已準備就緒。接著,UI 執行緒會尋找轉譯器程序,進行網頁轉譯作業。
由於網路要求可能需要幾百毫秒才能獲得回應,因此會採用加快此程序的最佳化速度。當 UI 執行緒在步驟 2 向網路執行緒傳送網址要求時,就能知道他要前往哪個網站。UI 執行緒會嘗試主動尋找或啟動轉譯器程序,同時與網路要求平行處理。這樣一來,如果一切正常,當網路執行緒收到資料時,轉譯器程序就會處於待命位置。如果導覽功能會跨網站重新導向,則系統可能無法使用這項待命程序。在這種情況下,系統可能需要其他程序。
步驟 5:修訂導覽
現在資料和轉譯器程序已準備就緒,會從瀏覽器程序將處理序間通訊 (IPC) 傳送至轉譯器程序,以修訂導覽。也會傳遞資料串流,讓轉譯器程序繼續接收 HTML 資料。當瀏覽器程序聽到轉譯器程序中確認修訂的訊息後,導覽就完成,文件載入階段也會開始。
此時,網址列會更新,安全性指標和網站設定使用者介面會反映新頁面的網站資訊。系統會更新分頁的工作階段記錄, 讓「上一頁」/「下一頁」按鈕能進入剛剛瀏覽的網站。為協助在關閉分頁或視窗時還原分頁/工作階段,工作階段歷史記錄會儲存在磁碟中。
額外步驟:初始載入完成
提交導覽後,轉譯器程序會載入資源並轉譯頁面。下一則訊息會詳細說明這個階段的情況。轉譯器程序「完成」轉譯後,會將處理序間通訊 (IPC) 傳回瀏覽器程序 (直到所有影格上的所有 onload
事件都觸發完畢,才會執行這項作業)。此時,UI 執行緒會停止分頁上的載入旋轉圖示。
我說「完成」,因為在此之後,用戶端 JavaScript 仍可載入其他資源並呈現新的檢視畫面
瀏覽至其他網站
簡單的導覽已經完成了!不過,如果使用者再次輸入網址列的網址,會發生什麼情況?瀏覽器程序同樣會進行相同的步驟前往其他網站。
但是在此之前,標記必須先與目前轉譯的網站確認對於 beforeunload
事件是否有相關要求。
當你嘗試離開或關閉分頁時,beforeunload
可以建立「要離開這個網站嗎?」快訊。
分頁中的所有內容 (包含 JavaScript 程式碼),都會由轉譯器程序處理,因此每當收到新的導覽要求時,瀏覽器程序都必須檢查目前的轉譯器程序。
如果導覽程序是透過轉譯器程序啟動 (例如使用者按下連結或用戶端 JavaScript 會執行 window.location = "https://newsite.com"
),轉譯器程序會先檢查 beforeunload
處理常式。然後執行與瀏覽器啟動瀏覽程序相同的程序。唯一的差別在於,轉譯要求會從轉譯器程序啟動至瀏覽器程序。
建立新的導覽至與目前轉譯的網站不同時,系統會呼叫獨立的轉譯程序來處理新的導覽,同時保留目前的轉譯程序來處理 unload
這類事件。詳情請參閱「網頁生命週期狀態總覽」,以及如何使用 Page Lifecycle API 連結到事件。
服務工作人員
這個導覽程序最近有一個異動就是引進 Service Worker。Service Worker 是一種在應用程式程式碼中寫入網路 Proxy 的方法,可讓網頁開發人員進一步控管本機快取項目,以及從網路取得新資料的時機。如果 Service Worker 已設為從快取載入網頁,就不需要從網路要求資料。
請特別注意,Service Worker 是會在轉譯器程序中執行的 JavaScript 程式碼。不過當瀏覽要求傳入時,瀏覽器程序如何知道網站是否有 Service Worker?
註冊 Service Worker 後,系統會將服務工作站的範圍保留為參考 (如要進一步瞭解範圍,請參閱這篇服務工作站生命週期文章)。進行導覽時,網路執行緒會根據已註冊的 Service Worker 範圍檢查網域,如果網址有登錄服務工作處理程序,UI 執行緒會尋找轉譯器程序,以執行 Service Worker 程式碼。服務工作站可能會從快取載入資料,因此不需從網路要求資料,也可以從網路要求新資源。
導覽預先載入
如果 Service Worker 最終決定向網路要求資料,瀏覽器程序與轉譯器程序之間的來回行程可能會延遲。導覽預先載入機制會在服務工作站啟動時同時載入資源,藉此加快這項程序。它會以標頭標示這些要求,讓伺服器可以決定針對這些要求傳送不同的內容。例如,僅更新資料,而非整份文件。
總結
在這篇文章中,我們將探討瀏覽期間會發生的情況,以及您的網頁應用程式程式碼 (例如回應標頭和用戶端 JavaScript 與瀏覽器互動) 如何。瞭解瀏覽器從網路取得資料的步驟後,就能輕鬆瞭解導覽預先載入等 API 的開發原因。在下一篇文章中,我們將深入探討瀏覽器如何評估 HTML/CSS/JavaScript 以顯示網頁。
您喜歡這篇貼文嗎?如果您對日後的文章有任何問題或建議,歡迎透過下方的留言專區或 Twitter 上的 @kosamari 與我們分享,