瀏覽器如何載入網站

在上一篇文章中,我們概述了構建網站的技術。在本文中,我們將介紹這些技術的渲染過程——當瀏覽器收到構成網頁的程式碼檔案和其他資產(如Web 如何工作中所述)後,它們是如何組合在一起以建立使用者互動的最終體驗的?

預備知識 熟悉您的計算機作業系統、Web 瀏覽器和 Web 技術的基本知識。
學習成果
  • HTTP 響應中返回的不同型別的資產。
  • 瀏覽器如何組裝不同的檔案以渲染網頁並將其顯示給使用者。
  • 為什麼瀏覽器有時被視為一個“充滿敵意”的程式設計環境,但同時也是一個很棒的程式設計環境。

HTTP 響應中返回哪些檔案?

總結一下我們在上一篇文章中看到的Web 技術概述,HTTP 響應(對網頁請求)通常會包含以下一些檔案型別

  • HTML 檔案,用於指定網頁內容及其結構。
  • CSS 檔案,用於指定樣式和佈局資訊。
  • JavaScript 檔案,用於指定網頁互動部分的行為。
  • 媒體資產,例如影像、影片、音訊檔案、PDFSVG,它們嵌入在網頁中或由瀏覽器顯示。
  • 瀏覽器無法本地處理的其他型別檔案,因此將其交給裝置上的相關應用程式進行渲染,例如 Word 或 Pages 文件、PowerPoint 幻燈片演示和 Open Office 檔案。

網頁渲染

當用戶導航到新網頁時(透過點選連結或在瀏覽器位址列中輸入網址),會發送多個 HTTP 請求,並在 HTTP 響應中返回多個檔案。這些響應中收到的檔案由瀏覽器處理並組合成一個使用者可以互動的網頁。將這些部分組裝成網頁的過程稱為渲染

以下部分將高階解釋瀏覽器如何渲染網頁。請記住,這是一個簡化的描述,不同的瀏覽器將以不同的方式處理該過程。但是,這仍然能讓您對事情的工作方式有所瞭解。

處理 HTML

首先,瀏覽器會接收並解析包含網頁內容並定義其結構的 HTML 檔案。瀏覽器將其轉換為樹狀結構,稱為 DOM 樹文件物件模型)。DOM 代表計算機記憶體中的 HTML 文件結構。以這個基本的 HTML 片段為例

html
<p>
  Let's use:
  <span>HTML</span>
  <span>CSS</span>
  <span>JavaScript</span>
</p>

HTML 中的每個元素、屬性和文字片段都成為樹結構中的一個 DOM 節點。節點由它們與其他 DOM 節點的關係定義。有些元素是子節點的父節點,子節點有兄弟節點。瀏覽器將解析此 HTML 並從中建立以下 DOM 樹

P
├─ "Let's use:"
├─ SPAN
|  └─ "HTML"
├─ SPAN
|  └─ "CSS"
└─ SPAN
    └─ "JavaScript"

在此 DOM 樹中,對應於我們 <p> 元素的節點是父節點。它的子節點包括一個文字節點和對應於我們三個 <span> 元素的三個節點。SPAN 節點也是父節點,其子節點是文字節點。當瀏覽器渲染此 DOM 樹時,它將如下所示

某些 HTML 元素在解析時會觸發更多 HTTP 請求

解析 CSS 和渲染頁面

接下來,處理 CSS。

  1. 瀏覽器會解析頁面中找到的 CSS(無論是包含在 HTML 檔案中,還是從外部樣式表中獲取),並根據它們將應用於哪些 HTML 元素(在 DOM 中表示為稱為節點的專案)將不同的 CSS 樣式規則分類到不同的“桶”中。然後,瀏覽器會根據需要將樣式附加到不同的元素(此中間步驟稱為渲染樹)。
  2. 渲染樹按照規則應用後應出現的結構進行佈局。這包括任何要嵌入頁面中的影像和其他媒體檔案。
  3. 頁面的視覺顯示呈現在螢幕上(此階段稱為繪畫)。

下圖展示了我們目前所討論過程的視覺化

Rendering process overview

回到我們的例子,假設在 HTML 檔案中找到以下 CSS

css
span {
  border: 1px solid black;
  background-color: lime;
}

CSS 中唯一的規則有一個 span 選擇器,所以瀏覽器可以非常快速地對 CSS 進行分類!它將該規則應用於 DOM 樹中的每個 SPAN 節點,給它們一個黑色邊框和石灰綠色背景,然後將最終的視覺表示繪製到螢幕上。

更新後的輸出如下

處理 JavaScript

處理完 CSS 後,頁面中找到的任何 JavaScript(無論是包含在 HTML 檔案中,還是從外部指令碼檔案中獲取)都會被解析、解釋、編譯和執行。這發生在最終頁面渲染完成之前的某個時刻——畢竟,一些 JavaScript 可能會影響渲染,例如透過向 DOM 新增節點或修改現有節點。

回到我們的例子,假設在 HTML 檔案中找到以下 JavaScript

js
const spans = document.querySelectorAll("span");
spans.forEach((span) => {
  const reversedText = span.textContent.split("").reverse().join("");
  span.textContent = reversedText;
});

您不需要完全理解此 JavaScript 的工作原理,但在高層次上,它會查詢 DOM 中每個 SPAN 節點並反轉其子文字節點中字元的順序。

最終輸出如下

還有哪些渲染步驟?

在頁面渲染過程中還會發生其他一些事情,但我們不會在這裡全部討論。值得一提的一個顯著的額外事件是,會根據 DOM 構建一個輔助功能樹,供輔助技術(例如螢幕閱讀器)接入,這使得無法看到渲染內容的人也能夠與之互動。

您將在稍後的輔助功能模組中瞭解更多資訊。

瀏覽器:一個“充滿敵意”一個很棒的程式設計環境

前端 Web 開發有時會令人沮喪,有些人認為瀏覽器是一個“充滿敵意”的程式設計環境。這是因為,與其他程式設計環境不同,它更難保證程式碼執行的環境。您無法提前知道使用者將擁有的作業系統、瀏覽器、語言、位置、網路連線、CPU、GPU、記憶體、電池壽命等所有不同組合,因此您無法保證所有使用者都能獲得完美的體驗。

現代瀏覽器傾向於相當一致地實現 Web 標準,但仍有許多不確定性需要應對。作為 Web 開發人員,您需要接受這種不確定性,進行防禦性程式設計,並保守地使用功能。這取決於遵守上一篇文章中概述的最佳實踐

從積極的一面來看,Web 也是一個很棒的程式設計環境,原因有很多。

  • 首先,它的設計考慮到了通用訪問。Web 的基本狀態是可訪問和可連結的。其中一些基本功能在其他環境中更難實現。
  • Web 上的應用程式交付既簡單又強大。您無需讓使用者經歷複雜的安裝過程:只需將他們指向一個網址,他們就可以開始使用。
  • 應用程式更新通常很簡單。在許多情況下,訪問者在重新載入瀏覽器選項卡時可以看到應用程式的新版本。您無需擔心讓訪問者定期下載和安裝軟體更新。
  • Web 社群充滿活力且樂於助人。正如我們稍後在研究和學習文章中討論的那樣,有很多地方可以尋求幫助,也有很多很棒的資源可以學習。

另見

何時以及如何向瀏覽器報告 bug

如果瀏覽器中某個功能未按預期工作,則可能是瀏覽器 bug。本文解釋瞭如何確定是否是 bug,以及如果是 bug 如何提交 bug 報告。