深入瞭解新式網路瀏覽器 (第 2 部分)

Mariko Kosaka

導航會發生什麼事

這是 4 篇網誌系列的第 2 集,介紹 Chrome 內部的運作方式。 在前一篇文章中,我們探討了不同的程序和執行緒如何處理瀏覽器的不同部分。在本文中,我們會深入探究每個程序和執行緒的通訊方式,以便顯示網站。

讓我們看看簡單的網路瀏覽用途:您在瀏覽器中輸入網址,接著瀏覽器會從網際網路擷取資料並顯示網頁。在這篇文章中,我們會著重在使用者要求網站 和瀏覽器準備為網頁轉譯前 (也稱為導覽) 的部分。

首先是瀏覽器程序

瀏覽器程序
圖 1:頂端的瀏覽器使用者介面/瀏覽器程序圖表,底部有使用者介面、網路和儲存空間執行緒

第 1 部分:CPU、GPU、記憶體和多程序架構所述,分頁外的所有內容都會由瀏覽器程序處理。瀏覽器程序包含可繪製按鈕和輸入欄位的執行緒,例如用於繪製按鈕和輸入欄位的網路執行緒;網路執行緒負責處理網路堆疊接收網際網路資料,以及控制檔案存取權的儲存空間執行緒等。當您在網址列中輸入網址時,瀏覽器程序的 UI 執行緒會處理輸入內容。

簡易導覽

步驟 1:處理輸入資料

當使用者開始在網址列中輸入內容時,UI 執行緒首先會詢問「這是一項搜尋查詢還是網址?」。在 Chrome 中,網址列也是搜尋輸入欄位,因此 UI 執行緒需要進行剖析,並決定是否將您傳送到搜尋引擎或您要求的網站。

處理使用者輸入內容
圖 1:UI 執行緒詢問使用者輸入內容是否為搜尋查詢或網址

步驟 2:開始導航

當使用者按下進入時,UI 執行緒會發出網路呼叫,以取得網站內容。載入旋轉圖示會顯示在分頁的角落,而網路執行緒會通過適當的通訊協定,例如 DNS 查詢並為該要求建立 TLS 連線。

導航開始
圖 2:與網路執行緒通訊的 UI 執行緒,即可前往 mysite.com

此時,網路執行緒可能會收到伺服器重新導向標頭,例如 HTTP 301。在這種情況下,網路執行緒會與伺服器要求重新導向的 UI 執行緒進行通訊。接著,系統會發出另一個網址要求。

步驟 3:朗讀回覆

HTTP 回應
圖 3:回應標頭,其中包含 Content-Type 和酬載,此為實際資料

回應主體 (酬載) 開始進入後,網路執行緒會視需要查看串流的前幾個位元組。回應的 Content-Type 標頭應會顯示資料類型,但因為內容可能遺漏或錯誤,所以這裡會執行「MIME 類型探測」。這是在原始碼中加註的「虛構商家」。 您可以閱讀註解,瞭解不同瀏覽器如何處理 content-type/payload 組合。

如果回應是 HTML 檔案,下一步就是將資料傳遞至轉譯器程序。如果是 ZIP 檔案或其他檔案,表示這是下載要求,因此需要將資料傳送給下載管理員。

MIME 類型探測
圖 4:網路執行緒詢問回應資料是否為來自安全網站的 HTML

系統也會執行SafeBrowsing檢查。如果網域和回應資料似乎與已知的惡意網站相符,網路執行緒快訊就會顯示警告頁面。此外,系統也會進行 Cross Origin Read Blocking (CORB) 檢查,以確保轉譯器程序不會接觸到敏感的跨網站資料。

步驟 4:尋找轉譯器程序

完成所有檢查,且網路執行緒確定瀏覽器應前往要求的網站後,網路執行緒會告知 UI 執行緒資料已準備就緒。接著,UI 執行緒會尋找轉譯器程序,進行網頁轉譯作業。

尋找轉譯器程序
圖 5:網路執行緒告知 UI 執行緒來尋找轉譯器程序

由於網路要求可能需要幾百毫秒才能獲得回應,因此會採用加快此程序的最佳化速度。當 UI 執行緒在步驟 2 向網路執行緒傳送網址要求時,就能知道他要前往哪個網站。UI 執行緒會嘗試主動尋找或啟動轉譯器程序,同時與網路要求平行處理。這樣一來,如果一切正常,當網路執行緒收到資料時,轉譯器程序就會處於待命位置。如果導覽功能會跨網站重新導向,則系統可能無法使用這項待命程序。在這種情況下,系統可能需要其他程序。

步驟 5:修訂導覽

現在資料和轉譯器程序已準備就緒,會從瀏覽器程序將處理序間通訊 (IPC) 傳送至轉譯器程序,以修訂導覽。也會傳遞資料串流,讓轉譯器程序繼續接收 HTML 資料。當瀏覽器程序聽到轉譯器程序中確認修訂的訊息後,導覽就完成,文件載入階段也會開始。

此時,網址列會更新,安全性指標和網站設定使用者介面會反映新頁面的網站資訊。系統會更新分頁的工作階段記錄, 讓「上一頁」/「下一頁」按鈕能進入剛剛瀏覽的網站。為協助在關閉分頁或視窗時還原分頁/工作階段,工作階段歷史記錄會儲存在磁碟中。

提交導覽
圖 6:瀏覽器和轉譯器程序之間的 IPC,要求轉譯網頁

額外步驟:初始載入完成

提交導覽後,轉譯器程序會載入資源並轉譯頁面。下一則訊息會詳細說明這個階段的情況。轉譯器程序「完成」轉譯後,會將處理序間通訊 (IPC) 傳回瀏覽器程序 (直到所有影格上的所有 onload 事件都觸發完畢,才會執行這項作業)。此時,UI 執行緒會停止分頁上的載入旋轉圖示。

我說「完成」,因為在此之後,用戶端 JavaScript 仍可載入其他資源並呈現新的檢視畫面

網頁完成載入
圖 7:從轉譯器到瀏覽器程序的 IPC,用於通知頁面「已載入」

簡單的導覽已經完成了!不過,如果使用者再次輸入網址列的網址,會發生什麼情況?瀏覽器程序同樣會進行相同的步驟前往其他網站。 但是在此之前,標記必須先與目前轉譯的網站確認對於 beforeunload 事件是否有相關要求。

當你嘗試離開或關閉分頁時,beforeunload 可以建立「要離開這個網站嗎?」快訊。 分頁中的所有內容 (包含 JavaScript 程式碼),都會由轉譯器程序處理,因此每當收到新的導覽要求時,瀏覽器程序都必須檢查目前的轉譯器程序。

beforeunload 事件處理常式
圖 8:從瀏覽器程序到轉譯器程序的 IPC,告知轉譯器程序即將前往其他網站

如果導覽程序是透過轉譯器程序啟動 (例如使用者按下連結或用戶端 JavaScript 會執行 window.location = "https://newsite.com"),轉譯器程序會先檢查 beforeunload 處理常式。然後執行與瀏覽器啟動瀏覽程序相同的程序。唯一的差別在於,轉譯要求會從轉譯器程序啟動至瀏覽器程序。

建立新的導覽至與目前轉譯的網站不同時,系統會呼叫獨立的轉譯程序來處理新的導覽,同時保留目前的轉譯程序來處理 unload 這類事件。詳情請參閱「網頁生命週期狀態總覽」,以及如何使用 Page Lifecycle API 連結到事件。

新導覽列和卸載
圖 9:從瀏覽器程序到新轉譯器程序的 2 個處理序間通訊 (IPC),要求轉譯網頁,並指示舊版轉譯器程序卸載

服務工作人員

這個導覽程序最近有一個異動就是引進 Service Worker。Service Worker 是一種在應用程式程式碼中寫入網路 Proxy 的方法,可讓網頁開發人員進一步控管本機快取項目,以及從網路取得新資料的時機。如果 Service Worker 已設為從快取載入網頁,就不需要從網路要求資料。

請特別注意,Service Worker 是會在轉譯器程序中執行的 JavaScript 程式碼。不過當瀏覽要求傳入時,瀏覽器程序如何知道網站是否有 Service Worker?

Service Worker 範圍查詢
圖 10:在瀏覽器程序中查詢 Service Worker 範圍的瀏覽器執行緒

註冊 Service Worker 後,系統會將服務工作站的範圍保留為參考 (如要進一步瞭解範圍,請參閱這篇服務工作站生命週期文章)。進行導覽時,網路執行緒會根據已註冊的 Service Worker 範圍檢查網域,如果網址有登錄服務工作處理程序,UI 執行緒會尋找轉譯器程序,以執行 Service Worker 程式碼。服務工作站可能會從快取載入資料,因此不需從網路要求資料,也可以從網路要求新資源。

服務工作者導航
圖 11:瀏覽器程序中的 UI 執行緒,會啟動轉譯器程序來處理服務工作站;轉譯器程序中的工作站執行緒接著向網路要求資料

如果 Service Worker 最終決定向網路要求資料,瀏覽器程序與轉譯器程序之間的來回行程可能會延遲。導覽預先載入機制會在服務工作站啟動時同時載入資源,藉此加快這項程序。它會以標頭標示這些要求,讓伺服器可以決定針對這些要求傳送不同的內容。例如,僅更新資料,而非整份文件。

預先載入導覽功能
圖 12:瀏覽器程序中的 UI 執行緒,會啟動轉譯器程序來處理服務工作站,同時同時啟動網路要求

總結

在這篇文章中,我們將探討瀏覽期間會發生的情況,以及您的網頁應用程式程式碼 (例如回應標頭和用戶端 JavaScript 與瀏覽器互動) 如何。瞭解瀏覽器從網路取得資料的步驟後,就能輕鬆瞭解導覽預先載入等 API 的開發原因。在下一篇文章中,我們將深入探討瀏覽器如何評估 HTML/CSS/JavaScript 以顯示網頁。

您喜歡這篇貼文嗎?如果您對日後的文章有任何問題或建議,歡迎透過下方的留言專區或 Twitter 上的 @kosamari 與我們分享,

下一步:轉譯器程序的內部運作