[譯]從內部瞭解現代瀏覽器(2)

biorz發表於2018-09-30

原文Mariko Kosaka

[譯]從內部瞭解現代瀏覽器(1)

[譯]從內部瞭解現代瀏覽器(2)

[譯]從內部瞭解現代瀏覽器(3)

導航會發生什麼

這是本系列部落格的第2部分。在上一篇文章中,我們研究了不同的程式和執行緒如何處理瀏覽器的不同部分。在這篇文章中,我們將深入研究每個程式和執行緒如何進行通訊以顯示網站。

讓我們看一下Web瀏覽的簡單用例:您在瀏覽器中鍵入URL,然後瀏覽器從Internet獲取資料並顯示頁面。在這篇文章中,我們將重點關注使用者請求網站的部分以及瀏覽器準備呈現頁面的部分 - 也稱為導航。

從瀏覽器程式開始

正如我們在 第1部分中所述:CPU,GPU,記憶體和多程式架構,選項卡外部的所有內容都由瀏覽器程式處理。瀏覽器程式具有諸如UI執行緒之類的執行緒,其繪製瀏覽器的按鈕和輸入欄位,處理網路堆疊從網際網路接收資料的網路執行緒,控制對檔案的訪問的儲存執行緒等。當您在位址列中鍵入URL時,您的輸入將先由瀏覽器程式的UI執行緒處理。

[譯]從內部瞭解現代瀏覽器(2)

圖1:瀏覽器UI、網路和儲存執行緒

一個簡單的導航

1.處理輸入

當使用者開始在位址列輸入時,UI執行緒首先要知道的是“這是搜尋查詢還是URL?”。在Chrome中,位址列也可以輸入搜尋欄位,因此UI執行緒需要解析並確定是將您的輸入傳送到搜尋引擎還是傳送到您請求的網站。

[譯]從內部瞭解現代瀏覽器(2)

圖2:UI執行緒詢問輸入是搜尋查詢還是URL

2.開始導航

當使用者點選回車時,UI執行緒啟動網路呼叫以獲取站點內容。載入標誌顯示在選項卡的一側,網路執行緒通過適當的協議,如DNS 為請求來查詢和建立TLS連線。

[譯]從內部瞭解現代瀏覽器(2)

圖3:UI執行緒與網路執行緒通訊以導航到mysite

此時,網路執行緒可以接收像HTTP 301這樣的伺服器重定向頭。比如,當伺服器請求重定向時,網路執行緒會與UI執行緒通訊,然後啟動另一個URL請求。

3.讀取伺服器響應

一旦響應主體(有效載荷)開始進入,網路執行緒會在必要時檢視流的前幾個位元組。響應的Content-Type欄位應該說明它是什麼型別的資料,但由於它可能丟失或錯誤,所以在這裡會完成MIME型別嗅探。這是原始碼中註釋的“棘手的業務”原始碼。您可以閱讀註釋,以瞭解不同的瀏覽器如何處理內容型別/有效載荷對。

[譯]從內部瞭解現代瀏覽器(2)

圖3:包含Content-Type和有效載荷的響應頭

如果響應是HTML檔案,那麼下一步就是將資料傳遞給渲染器程式,但如果它是zip檔案或其他檔案,則表示它是下載請求,因此需要將資料傳遞給下載管理器。

[譯]從內部瞭解現代瀏覽器(2)

圖4:網路執行緒詢問響應資料是否是來自安全站點的HTML

這也是SafeBrowsing檢查發生的地方。如果域和響應資料似乎與已知的惡意站點匹配,則網路執行緒會發出警告以顯示警告頁面。此外, 還會發生Cross Origin Read Blocking(CORB)檢查,以確保敏感的跨站點資料無法進入渲染器程式。

4.查詢渲染器程式

完成所有檢查並且網路執行緒確信瀏覽器應導航到所請求的站點後,網路執行緒會告知UI執行緒資料已準備就緒。然後,UI執行緒找到渲染器程式以進行網頁的渲染。

[譯]從內部瞭解現代瀏覽器(2)

圖5:網路執行緒與ui執行緒

由於網路請求可能需要幾百毫秒才能得到響應,因此做了加速此過程的優化。當UI執行緒在步驟2向網路執行緒傳送URL請求時,它已經知道他們正在導航到哪個站點。UI執行緒嘗試與網路請求並行地主動查詢或啟動渲染器程式。這樣,如果一切按預期進行,則當網路執行緒接收資料時,渲染器程式已處於備用位置。如果導航重定向跨站點,則可能不會使用此備用程式,在這種情況下可能需要其他不同的程式;

5.提交導航

現在資料和渲染器程式已準備就緒,瀏覽器程式將通過IPC傳送到渲染器程式以提交導航。它還會傳遞資料流,因此渲染器程式可以繼續接收HTML資料。一旦瀏覽器程式監聽到確認提交已在渲染器程式中發生,導航就完成了,文件載入階段就開始了。

此時,位址列會更新,安全指示器和站點設定UI會反映新頁面的站點資訊。選項卡的會話歷史記錄將被更新,因此後退/前進按鈕也會被應用新的記錄。為了在關閉選項卡或視窗時簡化選項卡/會話還原,會話歷史記錄會儲存在磁碟上。

[譯]從內部瞭解現代瀏覽器(2)

圖6:瀏覽器程式和渲染器程式間的ipc,請求渲染頁面

最後,初始化載入完成

提交導航後,渲染器程式繼續載入資源並呈現頁面。 我們將在下一篇文章中詳細介紹現階段的情況。 一旦渲染器程式“完成”渲染,它就會將一個IPC傳送回瀏覽器程式(這是在所有onload事件觸發了包含頁面中的所有框架,並且完成執行event handler之後)。 此時,UI執行緒會停止選項卡上的載入標誌。 我說的“完成”,因為客戶端JavaScript仍然可以載入額外的資源並在此之後呈現新的檢視。

[譯]從內部瞭解現代瀏覽器(2)

圖7:渲染器程式告知瀏覽器程式渲染完成

導航到其他的站點

簡單的導航到此已經完成,但是當使用者在位址列再次鍵入了其他的地址將會發生什麼呢?是的,瀏覽器程式會進行相同的步驟去導航到不同的網址;但是,在這之前,瀏覽器程式會檢查當前被渲染的網站是否具有beforeupload

beforeupload會建立一個“你確定要離開此站點”的警告當你想導航到其他的站點或者關閉這個標籤;你的所有javascript程式碼將被渲染器程式處理,所以瀏覽器程式必須在新導航進入的時候檢查當前的渲染器程式;

警告:不要新增無條件的beforeunload事件處理程式。 它會產生更多延遲,因為在啟動導航之前需要執行處理程式。 應僅在需要時新增此事件處理程式,例如,警告使用者他們可能會丟失他們在頁面上輸入的資料。

[譯]從內部瞭解現代瀏覽器(2)

圖8:瀏覽器程式告知渲染器程式導航將要變更

如果導航是從渲染器程式啟動的(如使用者單擊連結或客戶端JavaScript已執行window.location =“newsite.com”),則渲染器程式首先檢查beforeunload處理程式。 然後,它進行與瀏覽器程式啟動導航相同的步驟。 唯一的區別是導航請求從渲染器程式到瀏覽器程式觸發的。

當新導航進入與當前渲染不同的站點時,將呼叫單獨的渲染過程來處理新導航,同時保持當前渲染過程以處理解除安裝等事件。 有關更多資訊,請參閱頁面生命週期狀態概述以及如何使用Page Lifecycle API鉤子事件。

[譯]從內部瞭解現代瀏覽器(2)

圖9:瀏覽器告知渲染器程式需要渲染頁面和解除安裝頁面

service worker

最近有關導航的一個改變是引入了service worker連結)。service worker是一種在應用程式程式碼中編寫網路代理的方法; 允許Web開發人員更好地控制本地快取內容以及何時從網路獲取新資料。如果將service worker設定為從快取載入頁面,則無需從網路請求資料。

重要的是service worker是在渲染器程式中執行的JavaScript程式碼。但是當導航請求進入時,瀏覽器程式如何知道該站點有service worker

[譯]從內部瞭解現代瀏覽器(2)

圖10:瀏覽器程式中的網路執行緒檢查service worker註冊域

註冊service worker時,將保留service worker的範圍作為參考(您可以在此“service worker生命週期”一文中閱讀有關範圍的更多資訊)。當導航發生時,網路執行緒根據註冊的service worker範圍檢查域,如果為該URL註冊了service worker,則UI執行緒找到渲染器程式以執行service worker程式碼。service worker可以從快取載入資料,無需從網路請求資料,或者可以從網路請求新資源。

[譯]從內部瞭解現代瀏覽器(2)

圖11:瀏覽器程式中的UI執行緒啟動渲染器程式以處理service worker; 然後,渲染器程式中的工作執行緒從網路請求資料

導航的預載入

您可以看到,如果service worker最終決定從網路請求資料,則瀏覽器程式渲染器程式之間的往返可能會導致延遲。 導航預載入( Navigation Preload)是一種通過與service worker並行載入資源來加速此過程的機制。 它會標記這些請求,允許伺服器決定為這些請求傳送不同的內容; 例如,只更新資料而不是完整文件。

[譯]從內部瞭解現代瀏覽器(2)

圖12:瀏覽器程式中的UI執行緒啟動渲染器程式以在並行的啟動網路請求的同時處理service work

總結

在這篇文章中,我們研究了導航過程中發生的情況以及響應頭和客戶端JavaScript等Web應用程式程式碼如何與瀏覽器互動。 瞭解瀏覽器通過網路獲取資料的步驟,可以更容易地理解為什麼開發導航預載入等API。 在下一篇文章中,我們將深入探討瀏覽器如何處理HTML / CSS / JavaScript以呈現頁面。

相關文章