對(duì)頁(yè)面中 DOM 元素的繪制是在多個(gè)層上進(jìn)行的生蚁。在每個(gè)層上完成繪制過(guò)程之后肋拔,瀏覽器會(huì)將所有層按照合理的順序合并成一個(gè)圖層氛魁,然后顯示在屏幕上编饺。對(duì)于有位置重疊的元素的頁(yè)面乖篷,這個(gè)過(guò)程尤其重要,因?yàn)橐坏﹫D層的合并順序出錯(cuò)透且,將會(huì)導(dǎo)致元素顯示異常撕蔼。
DOM 樹(shù)中每個(gè)節(jié)點(diǎn)都會(huì)對(duì)應(yīng)一個(gè) LayoutObject
,LayoutObject
知道如何在屏幕上 paint Node 的內(nèi)容秽誊。當(dāng)LayoutObject
處于相同的坐標(biāo)空間時(shí)鲸沮,就會(huì)形成一個(gè)RenderLayers
(PaintLayer
) ,也就是渲染層锅论。PaintLayer 最初是用來(lái)實(shí)現(xiàn) stacking contest(層疊上下文)讼溺,以此來(lái)保證頁(yè)面元素以正確的順序合成(composite),這樣才能正確的展示元素的重疊以及半透明元素等等最易。因此滿足形成層疊上下文條件的 LayoutObject 一定會(huì)為其創(chuàng)建新的渲染層怒坯。
創(chuàng)建PaintLayer
常見(jiàn)的 3 類:
- NormalPaintLayer
- 根元素(HTML)
- 有明確的定位屬性(relative炫狱、fixed、sticky剔猿、absolute)
- 透明的(opacity 小于 1)
- 有 CSS 濾鏡(fliter)
- 有 CSS mask 屬性
- 有 CSS mix-blend-mode 屬性(不為 normal)
- 有 CSS transform 屬性(不為 none)
- backface-visibility 屬性為 hidden
- 有 CSS reflection 屬性
- 有 CSS column-count 屬性(不為 auto)或者 有 CSS column-width 屬性(不為 auto)
- 當(dāng)前有對(duì)于 opacity视译、transform、fliter归敬、backdrop-filter 應(yīng)用動(dòng)畫(huà)
- OverflowClipPaintLayer(overflow 不為 visible)
- NoPaintLayer(不需要 paint 的 PaintLayer酷含,比如一個(gè)沒(méi)有視覺(jué)屬性(背景、顏色弄慰、陰影等)的空 div)
滿足以上條件的 LayoutObject 會(huì)擁有獨(dú)立的渲染層第美,而其他的 LayoutObject 則和其第一個(gè)擁有渲染層的父元素共用一個(gè)
從 PaintLayers 到 GraphicsLayers
某些特殊的渲染層會(huì)被認(rèn)為是合成層(Compositing Layers)蝶锋,合成層擁有單獨(dú)的 GraphicsLayer陆爽。而其他不是合成層的渲染層,則和其第一個(gè)擁有 GraphicsLayer 父層公用一個(gè)扳缕。
渲染層提升為合成層的原因有一下幾種:
RenderLayers
(PaintLayer
) 來(lái)保證頁(yè)面元素以正確的順序合成慌闭,這時(shí)候就會(huì)出現(xiàn)層合成(composite)
- RenderLayers 渲染層,這是負(fù)責(zé)對(duì)應(yīng) DOM 子樹(shù)
- GraphicsLayers 圖形層躯舔,這是負(fù)責(zé)對(duì)應(yīng) RenderLayers 子樹(shù)
每個(gè) GraphicsLayer 都有一個(gè) GraphicsContext驴剔,GraphicsContext 會(huì)負(fù)責(zé)輸出該層的位圖,位圖是存儲(chǔ)在共享內(nèi)存中粥庄,作為紋理上傳到 GPU 中丧失,最后由 GPU 將多個(gè)位圖進(jìn)行合成,然后 draw 到屏幕上惜互,此時(shí)布讹,我們的頁(yè)面也就展現(xiàn)到了屏幕上
渲染層提升為合成層的原因有一下幾種:
直接原因
- 硬件加速的 iframe 元素
- video 元素
- 覆蓋在 video 元素上的視頻控制欄
- 3D Canvas 提升為合成層
- 3D transform
- backface-visibility: hidden
- 對(duì) opacity、transform训堆、fliter描验、backdropfilter 應(yīng)用了 animation 或者 transition(需要是 active 的 animation 或者 transition,當(dāng) animation 或者 transition 效果未開(kāi)始或結(jié)束后坑鱼,提升合成層也會(huì)失效)
- will-change 設(shè)置為 opacity膘流、transform、top鲁沥、left呼股、bottom、right(其中 top画恰、left 等需要設(shè)置明確的定位屬性彭谁,如 relative 等)
后代元素原因
有合成層后代同時(shí)本身有 transform、opactiy(小于 1)阐枣、mask马靠、fliter奄抽、reflection 屬性