天天看點

【譯】解密 Quantum:現代浏覽器引擎的建構之道解密 Quantum:現代浏覽器引擎的建構之道

<b>本文講的是【譯】解密 Quantum:現代浏覽器引擎的建構之道,</b>

但是,我們意識到對于那些不從事浏覽器開發的人來說(而且是大多數人),很難明白這些改動對于 Firefox 的重大意義。畢竟,許多改動對于使用者來說是不可見的。

意識到這點後,我們開始撰寫一系列部落格文章來深度解讀 Quantum 項目正在做什麼。我們希望這一系列的文章能夠幫助大家了解 Firefox 的工作原理,以及 Firefox 是如何打造一款下一代浏覽器引擎,進而更好地利用現代計算機的硬體性能。

作為這系列文章的第一篇,最好還是先說明一下 Quantum 正在改變哪些核心内容。

浏覽器引擎是什麼?它的工作原理又是什麼?

那麼,就從頭開始說起吧。

Web 浏覽器是一種軟體,它首先加載檔案(通常這些檔案來自于遠端伺服器),然後在本地顯示這些檔案,并且允許使用者互動。

Quantum 是項目的代号,Mozilla 啟動這個項目是為了大幅度更新 Firefox 浏覽器的某個子產品,這個子產品決定了浏覽器如何根據遠端檔案将網頁顯示給使用者。這一子產品的行業術語叫“浏覽器引擎”,如果沒有浏覽器引擎,使用者就隻能看看網站源代碼而不能浏覽網站了。Firefox 的浏覽器引擎叫 Gecko。

可以簡單地把浏覽器引擎看作一個黑盒(有點類似于電視機),灌入資料後由黑盒來決定展示在螢幕上的資料形态。現在的問題是:浏覽器引擎是如何呈現頁面的?它是通過哪些步驟将資料轉化為我們所看見的網頁?

<a href="https://link.juejin.im/?target=https%3A%2F%2Fuser-gold-cdn.xitu.io%2F2017%2F5%2F17%2F038792e208d3747eba4caf670973774e" target="_blank"></a>

網頁資料通常有許多類型,但總的來說可以劃分為三大類:

用于描述網頁結構的代碼

用于提供樣式的代碼,描述了網頁結構的視覺外觀

用于控制浏覽器行為的腳本代碼,包括:計算、人機互動以及修改已初始化的網頁結構和樣式。

浏覽器引擎将頁面結構和樣式結合進而在螢幕上渲染出網頁,同時确定可以互動的内容。

浏覽器引擎包含一類稱為解析器的特殊子產品,它将資料從一種格式轉換為另一種可以存儲在浏覽器記憶體中的格式。舉個例子,HTML 解析器拿到了以下 HTML 内容:

于是,解析器開始解析、了解 HTML,下面是解析器的獨白:

<a href="https://link.juejin.im/?target=https%3A%2F%2Fuser-gold-cdn.xitu.io%2F2017%2F5%2F17%2Feaf7e75b369f3038cb8c35453f6d7c0d" target="_blank"></a>

<a href="https://link.juejin.im/?target=https%3A%2F%2Fuser-gold-cdn.xitu.io%2F2017%2F5%2F17%2Feaf7e75b369f3038cb8c35453f6d7c0d" target="_blank">A diagram showing the nesting of HTML elements</a>

除了用于描述頁面結構,HTML 同樣包含指向樣式檔案和腳本檔案的位址。浏覽器發現這些後,就開始請求并加載資料。然後浏覽器會根據資料的類型,指定相應的解析器來處理。腳本檔案可以在 HTML 檔案解析的同時,改變頁面的結構和樣式。而樣式規則,CSS, 在浏覽器引擎中發揮以下作用。

CSS 是一門程式設計語言,開發者可以借助 CSS 描述頁面元素的外觀。CSS 全稱 Cascading Style Sheets (譯注:層疊樣式表),之是以這樣命名是因為多個 CSS 指令可以作用在同一個元素上,後定義的指令可以覆寫之前定義的指令,權重高的指令可以覆寫權重低的指令(這就是層疊的概念)。下面是一些 CSS 代碼。

大部分 CSS 代碼被分割在稱為規則的一個個分組中,每條規則包含兩個部分。其中一個部分是選擇器,選擇器描述了 DOM 中需要應用樣式的元素(上文說過,還記得嗎?)。另一部分則是一系列樣式聲明,應用于與選擇器比對的元素。浏覽器引擎中包含一個名為樣式引擎的子系統,用于接收 CSS 代碼,并将 CSS 規則應用到由 HTML 解析器生成的 DOM 中。

<a href="https://link.juejin.im/?target=https%3A%2F%2Fuser-gold-cdn.xitu.io%2F2017%2F5%2F17%2Fcbc1372a4eb5a1ad4404b541b16ec4f3" target="_blank"></a>

舉個例子,在上述 CSS 中,我們有一條規則指定了選擇器 “section”,這會比對到 DOM 中所有 section 元素。接着,浏覽器引擎會為 DOM 中的每一個元素附上樣式注解。直到最後每個 DOM 元素都應用了樣式,我們将該狀态稱為元素樣式計算完畢。而當多個選擇器作用在一個元素上時,源代碼次序靠後的或者權重更高的 CSS 規則最終會應用到元素上。可以認為樣式表是層疊的薄透寫紙,上層覆寫下層,但同時也能讓下層透過上層顯示出來。

一旦浏覽器引擎計算好了樣式,接下來就要派上用場了!布局引擎接下來會接手 DOM 和已計算的樣式,并且會考慮待繪制布局所在的視窗大小。然後布局引擎會分析該元素應用的所有樣式,并通過各種算法将每個元素繪制在一個個内容盒子中。

<a href="https://link.juejin.im/?target=https%3A%2F%2Fuser-gold-cdn.xitu.io%2F2017%2F5%2F17%2F0044636aac9e933ecadc53b5219c6ee5" target="_blank"></a>

頁面布局繪制完畢後,是時候将頁面藍圖轉化成你所看見的實際頁面了。這一步驟稱為 painting(繪制),這也是先前所有步驟的最終整合。每個由布局定義的内容盒子都将被繪制,其内容來自 DOM,其樣式源自 CSS。最終,從代碼一步步重組而成的頁面,展現在使用者眼中。

以上就是以前的浏覽器引擎所做的事情。

當使用者滾動頁面的時候,浏覽器會進行重繪來顯示原先在可見視窗外的頁面内容。然而,顯然使用者都喜歡滾動頁面!浏覽器引擎清楚地意識到自己肯定會被要求展示初始視窗以外的内容(也稱視口)。現代浏覽器根據這個事實在頁面初始化的時候繪制了比視口更多的頁面内容。當使用者滾動頁面的時候,這部分使用者想要看的内容早就已經繪制完畢了。這樣的好處就是頁面滾動變得更快更流暢。這種技術是網頁合成的基礎,合成是一種減少所需繪制量的技術術語。

另外,我們有時候也需要重繪部分頁面内容。比如使用者有可能正在觀看一個每秒 60 幀的視訊。也可能頁面上有一個圖檔輪播或者滾動清單。浏覽器能夠檢測出頁面上哪一部分内容将要移動或者更新,并且會為這些更新的内容建立一個新的圖層,而非重新渲染整個頁面。一個頁面可以由多個彼此重疊的圖層構成。每個圖層都可以改變定位方式、滾動位置、透明度或者在不觸發重繪的前提下控制圖層的上下位置!相當友善。

有時候一些腳本或者動畫會修改元素的樣式。這個時候,樣式引擎就需要重新計算這個元素的樣式(可能頁面上許多其他元素也要重新計算),重新計算布局(産生一次回流),然後重繪整個頁面。随着計算量的增加,這些操作會耗費很多時間,但隻要發生的頻率低,那麼就不會對使用者體驗産生負面影響。

在現代 web 應用中,文檔結構經常會被腳本改變。而哪怕隻是一點小改動,都會或多或少地觸發整個渲染流程:HTML 解析成 DOM、樣式計算、回流、重繪。

<a href="https://link.juejin.im/?target=https%3A%2F%2Fuser-gold-cdn.xitu.io%2F2017%2F5%2F17%2F9c358ed0921de2a34f9cd5bab19ee2fc" target="_blank"></a>

不同浏覽器解釋 HTML、CSS 和 JavaScript 的方式也不一樣。這就産生了各種影響:小到細微的視覺差異,大到使用者無法在某些浏覽器上正常浏覽網站。近年來在現代網際網路中,大多數網站在不同浏覽器下似乎都表現的不錯,而且也沒有關注使用者具體使用的是什麼浏覽器。那麼,不同浏覽器又是如何達到這種程度的一緻性體驗呢?

為什麼說 Web 标準是重要的?因為隻要保證遵循了 Web 标準,就可以開發出一個全新的浏覽器引擎,這個引擎可以處理網際網路上數以億計的網頁,并繪制出和其它浏覽器一樣的結果。這也意味着在某些浏覽器中才能運作的“秘密配方”不再是秘密了(譯者注:例如,不再需要 CSS 私有字首)。另外,正因為 Web 标準的存在,使用者可以憑自己的喜好挑選浏覽器。

顧客買電腦的時候不單單考慮運作速度,畢竟速度快的電腦很可能非常耗電、非常容易發熱還非常貴!有時候人們想要一台續航時間良好的筆記本電腦。有時候呢,人們又想要一個微型的觸屏電腦,帶攝像頭,又小到可以塞進口袋,并且電量足夠用一天!計算能力的進步已經讓這成為可能(真的很驚人!),不過代價就是運作速度下降。正如你在飙車的時候無法有效(或者說安全)地控制行車路線,你也無法讓電腦超負荷計算的同時處理大量任務。現在的解決方案都是借助于單 CPU 多核。是以,現在智能手機普遍都有 4 個較小、較弱的計算核心。

不幸的是,過去的浏覽器設計是基于摩爾定律(性能提升)會繼續有效的假設。另外,編寫能夠充分利用多核 CPU 的代碼也是極為複雜的。是以,我們該如何在這個到處都是小型計算機的時代,開發一款高速又高效的浏覽器呢?

我們已經想到了!

皮皮蝦,我們走!

<b></b>

<b>原文釋出時間為:2017年5月17日</b>

<b>本文來自雲栖社群合作夥伴掘金,了解相關資訊可以關注掘金網站。</b>

繼續閱讀