摘要:既然出現(xiàn)了,那怎么辦,目前并沒聽說出現(xiàn)什么新的技術(shù)替代它雖然它真的已經(jīng)很不適合現(xiàn)代的前端了,那么只能開發(fā)一個新的引擎提高性能,這就是火狐家的量子引擎又叫。這就是所謂的,火狐前一個引擎所做的那樣。
開始
本文翻譯自Inside a super fast CSS engine: Quantum CSS ,如果想要閱讀原文,可以點擊前往,以下內(nèi)容夾雜本人一些思考,翻譯也并不一定完全。
碎碎念為什么翻譯這篇文章尼,一開始只是好奇,基本在前端技術(shù)圈子混過都知道火狐正在用Rust語言開發(fā)新的瀏覽器引擎,作為前端開發(fā)對火狐的感情還是大大的有(雖然現(xiàn)在已經(jīng)離不開chrome了),但是還是希望火狐能夠再次引領(lǐng)Web的變革。
可以說前端這幾年解決了前端工程化的很多痛點,但是性能這個坎依舊,期望webassembly盡快普及,但是對于前端必定又是一場腥風(fēng)血雨,前端不會一直是現(xiàn)在這樣的前端。既然webassembly出現(xiàn)了,那css怎么辦,目前并沒聽說出現(xiàn)什么新的技術(shù)替代它(雖然它真的已經(jīng)很不適合現(xiàn)代的前端了),那么只能開發(fā)一個新的引擎提高性能,這就是火狐家的量子引擎:Quantum CSS(又叫Stylo)。
這是火狐正在開發(fā)的Quantum項目,目的當(dāng)然是為了讓瀏覽器更快,從上圖可以看得到各個模塊,而Quantum CSS處于中間位置,這跟它在整個渲染過程中的位置一樣,利用Rust可以相當(dāng)有效利用現(xiàn)代處理器多核心的特性,能夠幾倍的提速。既然這么厲害,那從哪里可以體驗?zāi)幔涸诨鸷麼ightly版進入about:config設(shè)置layout.css.servo.enabled 屬性為 true就可以體驗這吊炸天的引擎。
站在巨人的肩膀上,當(dāng)然除了利用現(xiàn)代處理器的并行能力,還借鑒當(dāng)前各家瀏覽器積累的一些優(yōu)化技術(shù),接下來會一一解析這些優(yōu)化技術(shù),如何讓引擎更快。
CSS引擎會干些啥工作CSS引擎是瀏覽器渲染引擎的一部分,而渲染引擎會把我們的HTML和CSS轉(zhuǎn)換成屏幕上的像素(也就是畫面吧)。
各家瀏覽器都會有自家的渲染引擎,例如谷歌的Blink,Edge的EdgeHTML,Safari的Webkit和火狐的Gecko,雖然有這么多引擎,但是他們都做著同樣的事情:把HTML和CSS渲染成我們可以感知的界面。
而他們內(nèi)部的工作需要:
首先解析HTML文檔,生成DOM節(jié)點樹,讓瀏覽器可以知道頁面的結(jié)構(gòu)和各個節(jié)點的關(guān)系。
然后就要弄清楚每個元素長什么樣子了,圓的還是方的,有邊框還是沒邊框等等;所以這個時候就需要知道每個元素需要應(yīng)該用什么樣式。
除了知道長的樣子,還要知道各個節(jié)點的位置和布局。引擎會為所有可見的節(jié)點都會創(chuàng)建一個box,但是box并不僅為DOM節(jié)點而創(chuàng)建,DOM節(jié)點內(nèi)部也可以有其他box,例如幾行文字。
知道該應(yīng)用的樣式和位置,現(xiàn)在輪到繪制這些box了,這個工作可能會在多個layer上發(fā)生。可以認(rèn)為就像舊時動畫制作技術(shù),在一張透明的膠片上繪制背景,在另外的膠片上繪制人物或者其他元素。這樣的話就如果人物會動起來的時候,就只用重新繪制人物那張膠片了,不用繪制其他的,這樣就省事好多了。
到了這一步現(xiàn)在我們有不同的膠片(layer),是時候開始合成了(composite),但是合成之前,我們可能還會應(yīng)用一些transform,旋轉(zhuǎn)啊,偏移啊等等。最后把他們按照層級堆在一起,背景在后,人物在前等等,然后最終渲染到屏幕上。
綜合后,我們可以知道CSS引擎開始計算樣式時需要兩樣?xùn)|西:DOM的節(jié)點樹和一系列的樣式規(guī)則。
CSS引擎會遍歷所有DOM節(jié)點并計算每個節(jié)點所應(yīng)用的樣式,它會讓DOM節(jié)點每個CSS屬性都有一個值,就算你在樣式表中并沒有聲明,它可能來自繼承或者默認(rèn)值,或者客戶端的樣式表(User Agent Style)。
可以認(rèn)為引擎就像填表格一樣,把這些最后計算出來的值一個一個填進去。
為了得到上面的表格,CSS引擎需要做兩件事:
搞清楚每個節(jié)點所應(yīng)用的樣式規(guī)則(selector matching)
把一些你沒有聲明的值,根據(jù)繼承或者默認(rèn)值補充上去(the cascade)
Selector matching首先找出配置當(dāng)前的節(jié)點的樣式規(guī)則,放到一個list上去,這里也包括客戶端的樣式表。
然后會計算各個樣式規(guī)則之間的權(quán)重,并且根據(jù)權(quán)重排序。
根據(jù)權(quán)重大小,得出最終應(yīng)用的樣式屬性的值。
級聯(lián)(The cascade)目的是為了讓CSS更容易編寫和維護,由于級聯(lián)的存在,你可以在body上設(shè)置color屬性,而li,p,span等元素可以直接使用同樣的color,不需要每個元素都要去定義一次。
為了實現(xiàn)這個功能,CSS引擎會從表格里面尋找一些屬性值仍然為空的值,如果屬性默認(rèn)是繼承的話,CSS引擎會從父節(jié)點那里繼承屬性值,如果所有父節(jié)點都沒有定義該屬性值的話,就會使用默認(rèn)的值。
現(xiàn)在我們的表格都填滿了
上述表格的形式,只是一種表現(xiàn)方式,引擎真實的內(nèi)部不是這樣的。CSS擁有成千上百的屬性,如果引擎為每個節(jié)點都生成這樣一張表,會很快耗掉所有內(nèi)存。
相反引擎內(nèi)部通常會使用style struct sharing,樣式的數(shù)據(jù)會集中在不同對象里面(style struct),然后使用指針指向這些對象。
這會很大程度上節(jié)省內(nèi)存,因為各個節(jié)點間都很有可能擁有相似的屬性值(例如兄弟節(jié)點間),另外因為很多屬性也是通過繼承獲取的,所以父節(jié)點可以跟子節(jié)點間共享這些屬性值。
如何讓這些工作更快如果我們不去優(yōu)化這些工作,整個樣式計算工作就會是這樣:
這是巨量的工作,而且并不僅僅在頁面加載的時候發(fā)生,它會隨著用戶的交互時刻都在存在(例如hover一個元素,CSS引擎需要從新計算樣式)。
這樣就意味著必須得去優(yōu)化樣式的計算工作,在過去20年,已經(jīng)測試過不同的優(yōu)化策略,而Quantum CSS則是組合利用這些最優(yōu)的優(yōu)化策略。
Run it all in parallel我們現(xiàn)在的CPU大多擁有多個核心,而Quantum CSS則會把不同DOM節(jié)點的樣式計算工作分配到不同的核心上去,但是實現(xiàn)也有相當(dāng)?shù)碾y度,其中一個原因就是DOM節(jié)點樹并不一定均勻的,這會導(dǎo)致其中一部分核心工作負(fù)荷比其他核心大。
為了讓各個核心工作負(fù)荷更加合理,Quantum CSS使用了一種技術(shù)稱作 work stealing,當(dāng)一個DOM節(jié)點被處理的時候,引擎可以把它的子節(jié)點計算工作分成幾個“work units”并且放進隊列中。
當(dāng)其中一個核心清空自身隊列的工作后,它能夠?qū)ふ移渌犃猩系钠渌鹷ork units然后執(zhí)行,這意味著我們不需要提前就去分配好工作,在運行時也會達(dá)到最高的工作效率。
在大部分瀏覽器里面,很難讓這種機制毫無錯誤的運行,而且CSS引擎本身就非常復(fù)雜,它在渲染引擎中兩個最復(fù)雜的模塊(DOM和layout)中間。這個過程非常容易產(chǎn)生bug,而且并行程序?qū)е碌腷ug非常難debug,可以通過這篇文章了解更多。
Speed up restyles with the Rule Tree對于每個DOM節(jié)點,CSS引擎需要遍歷所有樣式規(guī)則去進行selector matching,且對于大部分節(jié)點這種matching并不會經(jīng)常改變。例如,用戶hover一個父節(jié)點,它的樣式規(guī)則可能會改變,但是我們?nèi)匀恍枰匦伦庸?jié)點的樣式規(guī)則去處理屬繼承的屬性值,而子節(jié)點之前匹配的規(guī)則很有可能不會改變。
如果我們記錄好子節(jié)點匹配哪些樣式規(guī)則,而不用每次都進行一次selector matching,這可能會得到很大的優(yōu)化。這就是所謂的rule tree,火狐前一個引擎所做的那樣。
CSS引擎會遍歷樣式規(guī)則幫DOM節(jié)點找出匹配的選擇器,然后根據(jù)權(quán)重排序,從而創(chuàng)建出一個樣式規(guī)則的鏈表,然后將這個鏈表添加到rule tree中。
CSS引擎會盡可能利用已有的分支,為rule tree保持最少的分支數(shù)。
如果大部分鏈表中大部分的選擇器,跟已存在的分支一樣,引擎會順著路徑,除非它到達(dá)一個節(jié)點,rule tree并不存在一樣分支,引擎就會添加一個新的分支。
在重新計算樣式的過程中,引擎會快速檢查父節(jié)點的改變是否會導(dǎo)致子節(jié)點匹配的樣式規(guī)則改變。如果沒有,子節(jié)點可以根據(jù)自己指向rule tree節(jié)點的指針計算樣式。引擎會rule tree的節(jié)點往上查找,獲取整個匹配的規(guī)則,從權(quán)重最大到權(quán)重最小的。這樣就可以很輕松的跳過selector matching這一步了。
但是這樣仍然還有很多工作要做,畢竟一個頁面上節(jié)點成千上萬,這時候并行計算的魔法又可以大顯神威了。
Speed up initial render (and the cascade) with the style sharing cache由于整個頁面的節(jié)點可能會有成千上萬個,它們當(dāng)中很多都匹配著相同的規(guī)則。例如wiki頁面中每個p元素其實逗匹配著相同的樣式規(guī)則,擁有一樣的computed styles。
如果這里沒有做優(yōu)化,可能每個段落都要重新計算,但是如果有一種方法來證明每個段落的樣式規(guī)則都是一樣,引擎就只需計算一次就可以了。
這就是所謂的style sharing cache,由Chrome和Safari所發(fā)明的一種優(yōu)化方式,在引擎處理一個節(jié)點后會把computed style放到cache里面,然后開始計算下一個節(jié)點的時候,引擎會先檢查cache里面是否已經(jīng)存在計算后的值。
而這些檢查包括:
兩個節(jié)點是否都有一樣的ID和Class等,如果一樣它們匹配同樣的規(guī)則。
對于非selector的行內(nèi)樣式,它們是否擁有一樣的值。
它們的父節(jié)點都是否指向同一個computed style object,如果一樣它們的繼承的值都會一樣。
但是也有很多其他的情況,導(dǎo)致這些檢查失效,例如:如果一個CSS規(guī)則使用了:first-child選擇器,就算兩個節(jié)點都已經(jīng)符合上述的規(guī)則,結(jié)果也會是檢查不通過。
在Webkit和Blink, style sharing cache在這些情況下會放棄檢查并不會使用cache。由于大部分網(wǎng)站都使用了這些modern selectors(CSS3),這個優(yōu)化的作用變得越來越少,所以Blink團隊最近把它移除了。
在Quantum CSS,我們收集了所有這些怪異的選擇器(CSS3)然后讓它們加入檢查。我們會把結(jié)果存儲為0和1,如果兩個元素?fù)碛型瑯拥?和1,那我們就知道他們是匹配同樣的樣式規(guī)則。
這樣我們就可以繼續(xù)享受style sharing cache帶來的優(yōu)化。
結(jié)束前半部分可以讓我們知道CSS引擎的工作內(nèi)容,后半部分讓我們了解新引擎是如何優(yōu)化性能的,真的學(xué)習(xí)了很多,我想你也一樣。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/91794.html
摘要:既然出現(xiàn)了,那怎么辦,目前并沒聽說出現(xiàn)什么新的技術(shù)替代它雖然它真的已經(jīng)很不適合現(xiàn)代的前端了,那么只能開發(fā)一個新的引擎提高性能,這就是火狐家的量子引擎又叫。這就是所謂的,火狐前一個引擎所做的那樣。 開始 本文翻譯自Inside a super fast CSS engine: Quantum CSS ,如果想要閱讀原文,可以點擊前往,以下內(nèi)容夾雜本人一些思考,翻譯也并不一定完全。 碎碎念...
摘要:既然出現(xiàn)了,那怎么辦,目前并沒聽說出現(xiàn)什么新的技術(shù)替代它雖然它真的已經(jīng)很不適合現(xiàn)代的前端了,那么只能開發(fā)一個新的引擎提高性能,這就是火狐家的量子引擎又叫。這就是所謂的,火狐前一個引擎所做的那樣。 開始 本文翻譯自Inside a super fast CSS engine: Quantum CSS ,如果想要閱讀原文,可以點擊前往,以下內(nèi)容夾雜本人一些思考,翻譯也并不一定完全。 碎碎念...
摘要:它是對于內(nèi)部的一個重大改寫,以達(dá)到讓更快運行的目的。擁有最高特異性的規(guī)則將會勝出。將來自于不同引擎的各種策略結(jié)合在一起,從而創(chuàng)造出一個超級快的新引擎。為了更平均的分配這些工作,使用了一個稱之為工作竊取的技術(shù)。 本文轉(zhuǎn)載自:眾成翻譯譯者:Mactavish鏈接:http://www.zcfy.cc/article/4041原文:https://hacks.mozilla.org/2017...
摘要:前端日報精選如何合理地設(shè)計的深入了解一個超快的引擎也稱全面了解作用域源碼分析二奇淫技巧總結(jié)整理下前端江湖面試對自己有益的題目。 2017-08-27 前端日報 精選 如何合理地設(shè)計Redux的State深入了解一個超快的 CSS 引擎: Quantum CSS (也稱?Stylo) ★ Mozilla Hacks全面了解JS作用域Zepto源碼分析(二)奇淫技巧總結(jié)整理下《前端江湖面試...
摘要:前端日報精選無頭瀏覽器初探鼠標(biāo)無限移動簡介譯深入分析變更檢測發(fā)布前必須排查的安全如何開發(fā)中文第期關(guān)鍵和減少阻塞渲染的的自動化解決方案譯網(wǎng)頁設(shè)計掘金年最受歡迎的個編程挑戰(zhàn)網(wǎng)站簡書系列和深入理解掘金發(fā)布后臺管理系統(tǒng),沒錯,它就是你想 2017-10-18 前端日報 精選 無頭瀏覽器 Puppeteer 初探鼠標(biāo)無限移動 JS API Pointer Lock簡介[譯] 深入分析 Angul...
閱讀 2472·2021-09-29 09:34
閱讀 3308·2021-09-23 11:21
閱讀 2501·2021-09-06 15:00
閱讀 1128·2019-08-30 15:44
閱讀 2029·2019-08-29 17:23
閱讀 3001·2019-08-29 16:44
閱讀 3060·2019-08-29 13:13
閱讀 1939·2019-08-28 18:12