火狐瀏覽器是如何又變快起來的?

發表於2017-12-03

人們已經注意到 Firefox 速度又變快了。

火狐瀏覽器是如何又變快起來的?

在過去的七個月裡,我們一直在迅速地更換著引擎的主要部件,在 Firefox 中使用了 Rust 和部分的 Servo。此外,有一個源於程式碼的問題,明顯或不明顯的嚴重影響瀏覽器效能。

我們稱之為“Project Quantum”,重生的首個 Firefox Quantum 常規版本將於明日釋出。

火狐瀏覽器是如何又變快起來的?

但這並不意味著我們的工作已經完成了,也不意味著今後 Firefox 的速度和響應速度不會再有進展。

那麼,讓我們來看看 Firefox 是如何再次變快的,以及它在哪部分變得更快。

使用 coarse-grained 並行作為基礎

為了變得更快,我們要利用在過去 10 年裡硬體的變化。

我們並不是第一個這樣做的。Chrome 在首次推出時就比 Firefox 更快,響應速度也更快。其中的一個原因就是 Chrome 的工程師看到了硬體的變化,並更好的利用了這一點。

火狐瀏覽器是如何又變快起來的?

一種新型的 CPU 開始變得流行。這些 CPU 擁有多個核心,這就意味著它們可以獨立完成任務,但同時也是並行的。

這可能會變得棘手。使用了 CPU 的並行性,可能會產生一些難以檢視且難以除錯的細微錯誤。例如,如果兩個核心需要在記憶體中對同一個陣列加一,如果沒有足夠小心,很容易出現一個將另一個覆蓋的問題。

火狐瀏覽器是如何又變快起來的?

一個很簡單的方法去避免這些各種各樣的 Bug 就是僅保證兩個東西(功能)的執行不會共享記憶體 —— 在你的程式裡把很大的任務拆分為不需要過多(協同)合作(的子任務),這就是粒度並行性。

在瀏覽器中,可相當容易找到這些粗粒,每一個選項卡都獨立地工作。還有圍繞該網頁的東西 —— Chrome 瀏覽器 —— 可以獨立處理。

這樣,頁面可以同時工作,而不會互相阻塞。如果在後臺選項卡中有長時間執行的指令碼,它不會阻塞前臺選項卡的工作。

這是 Chrome 工程師所預見的機會,我們也看到了,但是我們實現它的道路更加顛簸。從我們有現存的程式碼基礎,我們需要計劃如何拆分程式碼庫,以利用多個核心。

火狐瀏覽器是如何又變快起來的?

過了段時間,我們實現了它。隨著這個“電解”專案的實現,我們最終實現了為所有使用者預設啟用多程式。量子(瀏覽器)已經使用粗粒度的並行性,甚至比其他一些專案更好。

火狐瀏覽器是如何又變快起來的?

電解

“電解”為量子專案奠定了基礎,它引入了一種類似於 Chrome 的多程式架構。因為這是一個重大的變化,我們和一小部分使用者在 2016 年開始緩慢地引入、測試它,然後在 2017 年年中推送給所有 Firefox 使用者。

量子合成器

火狐瀏覽器是如何又變快起來的?

量子合成器把合成器轉移到自己的程式中。這裡最大的成功是使得 Firefox 更穩定。有一個單獨的程式就意味著一旦影像驅動崩潰,它不僅不會使得所有的 Firefox 的所有頁面崩潰,這個獨立的程式使得 Firefox 更具響應能力。

Quantum DOM

即使在核心之間拆分內容視窗,併為每個核心分配一個主執行緒,主執行緒仍然需要執行很多工。而其中一些比其他更重要。例如,響應按鍵比執行垃圾收集更重要。Quantum DOM 為我們提供了一種優先處理這些任務的方法。 這使得 Firefox 更具響應能力。這項工作大部分已經落地,但是我們仍然計劃進一步採取一些稱作搶先式排程的方法。

充分利用硬體的 fine-grained 並行性

然而,當我們展望未來時,我們需要比 coarse-grained 並行更進一步。

火狐瀏覽器是如何又變快起來的?

coarse-grained 並行更好地利用了硬體…但並沒有充分利用硬體。當你把網頁分給不同的核心去做時,有些核心可能就沒有被分配到工作。因此這些核心就會閒置下來。與此同時,如果 CPU 是單核的話,由新核心啟動新頁面的時間就會變得更長。

火狐瀏覽器是如何又變快起來的?

如果能夠使用所有的核心來處理新頁面,這將非常好。這樣你就可以更快地完成這項工作了。

但是如果使用 coarse-grained 並行,你不能把任何任務從一個核心分離到另一個核心,任務之間是沒有界限的。

通過 fine-grained 並行,你可以將一個更大的任務分解成更小的單元以便於傳送給不同的核心去處理。例如,如果你有類似於 Pinterest 的網站,你可以把它分成不同的固定模組,將它們傳送給不同的核心去處理。

火狐瀏覽器是如何又變快起來的?

這不僅有助於緩解像粗粒度並行這樣的延遲。它也有助於速度的提升。頁面會載入得更快,因為計算被分解到了不同的計算核心。隨著您新增更多的計算核心,頁面會載入越快。

所以我們看到這是未來,但是如何到達那裡並不完全清楚。由於要使這種細粒度的並行更快,通常需要在核心之間共享記憶體。但是這會帶來我們之前談到的那些資料競爭的問題

但是我們知道瀏覽器必須做這個轉變,所以我們開始投資研究。我們建立了一個沒有這些資料競爭問題的語言 —— Rust。然後,我們建立了一個瀏覽器引擎 —— Servo,以充分利用這種細粒度的並行性。通過這,我們證明了這一點可以發揮作用,並且在加快速度的同時可以減少錯誤的發生。

火狐瀏覽器是如何又變快起來的?

Quantum CSS (也稱作 Stylo)

火狐瀏覽器是如何又變快起來的?

使用 Stylo,CSS 樣式渲染的工作在所有 CPU 核心中完全並行化。Stylo 使用了一個稱為“工作竊取(work stealing)”的技術來高效地分離核心之間的工作,使得每個核心都保持忙碌的狀態。通過該技術,會得到一個線性的加速效果。可通過使用擁有的所有核心來為 CSS 的樣式渲染分配時間。

Quantum Render (具有 WebRender 特性)

火狐瀏覽器是如何又變快起來的?

有關硬體的另一部分是可以高度並行的 GPU,它擁有成百上千的核心。即便如此,我們仍然需要確保讓 GPU 的多核儘可能地保持工作狀態,從而提升效率,這就是 WebRender 所做的工作

WebRender 計劃於 2018 年推出,它將充分利用現代 GPU。同時,我們也從另一個角度來解決這個問題。高階圖層專案修改了 Firefox 的現有圖層系統以支援批量渲染。通過優化 Firefox 當前的 GPU 使用模式,我們獲得了立竿見影的效果。

???

我們認為渲染管道的其他部分也可以從這種細粒度的並行中受益。在接下來的幾個月中,我們將仔細研究一下,看看還能在哪些地方使用這些技術。

我們保證 Firefox 會越來越快,再也不會變慢

除了我們必須要做的這些重大的架構改變之外,一些效能缺陷也在我們沒有注意的情況下進入了程式碼庫。

所以我們新建了量子的另外一部分去修復它,它會發現這些問題,然後 Mozilla 團隊會解決這些問題。

火狐瀏覽器是如何又變快起來的?

Quantum Flow

Quantum Flow 的團隊是強大的,但他們不關注具體子專案的進度,他們主要關注的是一些特殊的場景,例如,社交媒體的資訊流的載入,和研究如何讓 Firefox 載入得更快。

Quantum Flow 給我們帶來了巨大的效能優勢。在此過程中,我們還開發了工具和具體流程為了更容易的找到了追蹤類似的問題。

Quantum Flow 現在怎麼樣了?

在這個過程中們非常成功 —— 一次識別並集中在一個關鍵案例上 —— 並把它變成我們的工作流程的一部分。為了做到這一點,我們將要提高我們的工具,所以我們不再需要一支專門的團隊來解決特定的問題,而是更多的工程師追蹤這些問題並解決問題。

但是用這種方法有一個難題。當我們優化一個用例時,我們需要逆優化另一個。為了防止這種現象,我們新增了許多新的跟蹤,包括改進 CI 自動化執行效能測試,遙測跟蹤使用者體驗,以及 bug 內部的迴歸管理。通過這些舉動,我們期望 Firefox Quantum 會越來越好。

明天只是個開始

明天對於在 Mozilla 的我們來說是一個重要的日子。在過去一年裡我們一直致力於讓 Firefox 變得更快,但這也僅僅只是一個開始。

在接下來的時間,我們會繼續釋出新的改進,並且和大家分享這些改進。

訪問 Try Firefox Quantum in Release 或者 Developer Edition 以確保大家可以獲取最新的更新。

相關文章