摘要:對應(yīng)多種語法規(guī)則可以為指定樣式。渲染頁面繪制到屏幕后,頁面結(jié)構(gòu)的改變也有可能導(dǎo)致渲染樹重新計算,其中重排和重繪是最耗時的部分。
寫了這么多class,color,background,display...; 也許有時候會疑惑,怎么就顯示在頁面上,改變元素的樣式。
本文簡明介紹整個解析,匹配,渲染過程
css 描述css 是Cascading Style Sheets的簡寫,是一種樣式表語言。對應(yīng)多種語法規(guī)則,可以為HTML 指定樣式。
基本規(guī)則圖片來源。
css 規(guī)則由兩部分組成:選擇器 和 聲明。上圖中element 對應(yīng)的類選擇器,緊接著聲明(Declaration)。
每條聲明由一個屬性(Property) 加冒號(:)和 一個值(value)加分號(;) 組成。
CSS 解析解析 html 或外部css 文檔,就是將文檔轉(zhuǎn)化成為有意義的結(jié)構(gòu),能夠讓代碼理解。解析結(jié)果代表了文檔結(jié)構(gòu)的節(jié)點樹,
解析分為詞法分析 和 語法分析。
詞法分析,也是編譯原理中的術(shù)語,從左到右一個字符一個字符的讀入源程序,對字符流進(jìn)行掃描,根據(jù)構(gòu)詞規(guī)則識別單詞,。這一過程可以使用lex等工具自動生成。
語法分析,主要任務(wù)是在詞法分析的基礎(chǔ)上,將單詞序列組合成各類語法短語,如“程序”, “語句”,“表達(dá)式”
解析工作通常會被拆分為兩個組件:
詞法分析器,負(fù)責(zé)將輸入流分解成有效的字符。
解析器,負(fù)責(zé)根據(jù)不同語言的語法規(guī)則來分析文檔結(jié)構(gòu),最后構(gòu)造出解析樹。
詞法分析器知道如何去除不相關(guān)的字符,比如空格和換行
具體到css解析,因為它是上下文無關(guān)的語法,可以利用各種解析器進(jìn)行解析。webkit 使用Flex 和 Bison 解析器生成器,通過css 語法文件自動創(chuàng)建解析器。解析器將CSS文件解析成StyleSheet對象,且每個對象都包含CSS規(guī)則。CSS規(guī)則包含選擇器和聲明對象。
上圖是 一個像素點的一生的ppt中選出圖片,感興趣可以看看演講視頻,非常直白,css樣式規(guī)則會被各種方式索引以便進(jìn)行快速有效的查找。實現(xiàn)各個樣式屬性的C++ 類,比如ppt中的BorderLeftColor類,是在構(gòu)建時Python腳本自動生成的。
具體到代碼實現(xiàn)中,webkit 使用CSSRuleSet 對象來保存style rule,在一般規(guī)則需要創(chuàng)建時,調(diào)用createStyleRule();
瀏覽器從右往左匹配選擇器在使用css選擇器進(jìn)行樣式匹配時,盡量少用層級關(guān)系,因為這樣可以減少選擇器匹配的次數(shù),提高css 解析效率。
其實瀏覽器使用從右到左的解析順序,同樣提高了效率。通常在寫css 樣式時,我們一貫的想法是,從左往右解析,從根節(jié)點開始,一層一層遍歷匹配,直到所有的選擇器都匹配上了。瀏覽器解析的順序正好相反。
從右往左匹配的好處簡單回顧下本次話題的上下文,也就是瀏覽器對頁面解析過程:
HTML parser 生成 Dom Tree
css parser 生成 style rules,也就是CSSOM tree。
Dom 與 CSSOM匹配完成后,最后結(jié)合生成render tree。
根據(jù) render tree 開始 布局
...
根據(jù)這張圖,可以對渲染過程大致了解。
回到瀏覽器匹配css 規(guī)則上,如果只有一個選擇器 對應(yīng)匹配一個元素,從左往右匹配看似非常合理,但是正常情況是,一個dom節(jié)點,比如,可能對應(yīng)了無數(shù)個css規(guī)則,沒有上限,我可以在上面加非常多的樣式。css 匹配效率的關(guān)鍵就是如何快速判斷盡可能多的選擇器并不能匹配。
先看看有多層嵌套的css規(guī)則。比如 #root .box .wrap i {}, 如果從左往右解析,最左邊開始, 直到最右邊的選擇器i, dom節(jié)點上根本沒有i標(biāo)簽, 遍歷到最后才排除css 規(guī)則。
相反,從最右邊的選擇器部分開始匹配,如果不成功,整個匹配過程就可以立刻結(jié)束;成功了,繼續(xù)往左,匹配父節(jié)點,跟樹的深度成正比。所以瀏覽器的匹配方式,可以非常快速的排除大部分的選擇器。
根據(jù)2009年在Firefox上做的測試,結(jié)論是僅僅從最右邊的選擇器開始檢查,就可以排除70%的規(guī)則??焖俪?/3的css規(guī)則后,后面只用擔(dān)心剩余的1/3。
樣式作用在DOM元素上從css文檔被解析器解析完成,將數(shù)據(jù)保存在對象模型中,獲取所有已解析的樣式規(guī)則,結(jié)合瀏覽器提供的默認(rèn)樣式,計算出每個DOM 元素最終的樣式值。保存在ComputedStyle對象模型中,它是由樣式屬性和值形成的map。
并且getComputedStyle 已經(jīng)暴露出來,在js中通過window.getComputedStyle,可以獲取元素的最終樣式。
如果多個element的computedStyle不通過計算可以確認(rèn)它們相等,那么這些elements只會計算一次樣式,其余的直接共享該ComputedStyle。
那些規(guī)則會共享computedStyle(待驗證):
該共享的element不能有id 屬性且CSS中還有該id的StyleRule,即使StyleRule 與 element 不匹配
tagName 和 class 屬性必須一樣。
mappedAttribute 必須相同。
不能使用sibling selector, 比如 :first-child, :last-child.
不能有style 屬性,哪怕style 屬性相同。他們也不會共享。
渲染p1
p2
頁面繪制到屏幕后,頁面結(jié)構(gòu)的改變也有可能導(dǎo)致渲染樹重新計算,其中重排和重繪是最耗時的部分。
在頁面的生命周期中,隨時都有可能發(fā)生重排(Layout)和重繪(Painting)
重排(reflow)當(dāng)可見節(jié)點位置 及尺寸發(fā)生變化時都會發(fā)生重排,而且重排開銷比重繪更大。
至少會有一次重排,發(fā)生在初始化頁面布局的時候。
觸發(fā)重排的幾種情況:
添加或刪除可見dom元素
元素位置改變
元素尺寸改變,
文字,內(nèi)容,字體發(fā)生改變
頁面初始化渲染
....
改變元素的外觀屬性(如background-color, border-color, visibility),不影響整個布局,瀏覽器就會根據(jù)元素的新屬性重新繪制。
重繪不會帶來重新布局
層合成(composite)DOM樹中每個節(jié)點的都對應(yīng)一個LayoutObject, 擁有相同的坐標(biāo)空間的LayoutObject,屬于同一渲染層(RenderLayers)。
渲染層保證元素按照正確順序合成(composite),正常展示元素的重疊以及元素透明等。
存在一些特殊情況,為滿足指定條件的LayoutObject會擁有獨立的渲染層,其他layoutobject則和第一個擁有渲染層的父元素公用一個。
利用chrome Devtools查看繪制過程。打開Chrome Devtools,按下Esc建
在出現(xiàn)的面板上 點擊左上角三點。
選擇rendering,轉(zhuǎn)到對應(yīng)標(biāo)簽。
打開后,頁面中閃爍的綠色區(qū)域,表示這塊需要重新繪制。
當(dāng)滾動側(cè)邊欄時,會出現(xiàn)整塊綠色
本文對css整個渲染過程進(jìn)行簡單介紹,試圖把大量復(fù)雜知識點串在一起,至少可以讓平時跟css打交道的我們,了解大致是個什么過程,同時也是對自己學(xué)習(xí)過程中的一次總結(jié)。對于里面涉及到的概念,都可以作為一個切入點,去好好研究。
參考鏈接Things nobody ever taught me about CSS
縮小樣式計算的范圍并降低其復(fù)雜性
為什么瀏覽器讀取css規(guī)則的順序是從右到左
why-do-browsers-match-css-selectors-from-right-to-left
【Hello CSS】第一章-CSS的語法與工作流
編譯原理之詞法分析、語法分析、語義分析
How Browsers Work: Behind the scenes of modern web browsers
前端代碼如何通過瀏覽器演化為屏幕顯示的像素
Webkit CSS引擎分析
簡化繪制的復(fù)雜度、減小繪制區(qū)域
無線性能優(yōu)化:Composite
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/116084.html
摘要:幸運的是,瀏覽器行為的基礎(chǔ)原理是相當(dāng)穩(wěn)定而且文檔齊全的,并且在相當(dāng)長一段時間內(nèi)肯定不會發(fā)生顯著變化。瀏覽器有種稱為預(yù)加載掃描器的東西,它會掃描的腳本,并開始預(yù)加載腳本,不過腳本只會在先前的節(jié)點已經(jīng)構(gòu)建完成后,才會依次執(zhí)行。 本文轉(zhuǎn)載自:眾成翻譯譯者:網(wǎng)絡(luò)埋伏紀(jì)事鏈接:http://www.zcfy.cc/article/2847原文:https://hackernoon.com/opt...
摘要:由一道面試題引發(fā)的思考從用戶輸入瀏覽器輸入到頁面最后呈現(xiàn)有哪些過程一道很常規(guī)的題目,考的是基本網(wǎng)絡(luò)原理,和瀏覽器加載,過程。所以抽出時間研究下瀏覽器渲染頁面的過程。 由一道面試題引發(fā)的思考: 從用戶輸入瀏覽器輸入url到頁面最后呈現(xiàn) 有哪些過程?一道很常規(guī)的題目,考的是基本網(wǎng)絡(luò)原理,和瀏覽器加載css,js過程。 答案大致如下: 用戶輸入URL地址 瀏覽器解析URL解析出主機(jī)名 瀏覽...
摘要:我們可以做很多事情來減少阻塞渲染的,例如,緩存等。但是如何減少阻塞渲染的為此,可以拆分并優(yōu)先加載首次渲染所需要的關(guān)鍵,然后再加載其它。請注意,文件在標(biāo)簽里引入,因此將會阻塞渲染。 showImg(https://segmentfault.com/img/remote/1460000011503289?w=600&h=321); 原文地址: Critical CSS and Webpa...
摘要:渲染引擎的概述渲染引擎的主要職責(zé)是在瀏覽器屏幕上顯示請求的頁面。中,渲染樹中的每個節(jié)點都被稱為的渲染器或渲染對象。坐標(biāo)系相對于根渲染器。增量只有一些渲染器以不影響整個樹的方式進(jìn)行更改。渲染器使其矩形在屏幕上無效。 到目前為止,在我們之前的JavaScript工作原理系列文章中,我們一直關(guān)注JavaScript作為一種語言,其功能,它如何在瀏覽器中執(zhí)行,如何優(yōu)化等等。 但是,當(dāng)您構(gòu)建We...
閱讀 2081·2023-04-26 02:23
閱讀 1821·2021-09-03 10:30
閱讀 1391·2019-08-30 15:43
閱讀 1221·2019-08-29 16:29
閱讀 573·2019-08-29 12:28
閱讀 2366·2019-08-26 12:13
閱讀 2254·2019-08-26 12:01
閱讀 2451·2019-08-26 11:56