創(chuàng)建布局樹后恍箭,經(jīng)過布局計算,我們得到了一個需要渲染的所有節(jié)點組成的樹狀結(jié)構(gòu)瞧省,包含計算出的每個節(jié)點的坐標位置扯夭。
下面,就需要去實際地繪制鞍匾。
注:瀏覽器渲染是在瀏覽器渲染進程進行的交洗。其中,瀏覽器渲染進程分為多個線程橡淑。從解析 HTML 和 CSS 到布局計算都是在主線程進行的构拳。
一、分層
我們看到的網(wǎng)頁是二維的梁棠,但事實上置森,為了實現(xiàn)頁面上一些復(fù)雜的效果,瀏覽器會將頁面劃分為不同的圖層符糊,根據(jù)不同屬性的優(yōu)先級凫海,將它們劃分在不同的圖層。
也就是說男娄,我們看到的網(wǎng)頁盐碱,實際上是三維的。
一層層的圖層疊放在一起沪伙,構(gòu)成了我們最終看到的網(wǎng)頁瓮顽。這也是 CSS 叫做層疊樣式表的原因。
在這一階段围橡,輸入的是帶有坐標位置的布局樹暖混,輸出的是圖層樹(layerTree)。
那么翁授,瀏覽器是如何判斷圖層劃分的呢拣播?
- 首先晾咪,所有的節(jié)點都直接屬于或間接屬于一個圖層
- 瀏覽器會為符合某一些條件的節(jié)點創(chuàng)建圖層
瀏覽器會為哪些節(jié)點創(chuàng)建圖層呢?
- 擁有層疊上下文屬性的元素:
- position元素
- 設(shè)置透明度的元素
- 使用 CSS 濾鏡的元素
等等贮配。谍倦。。泪勒。
- 需要剪裁的地方:
若一段文本的長度超出了它的父容器的大小昼蛀,則文本會被剪裁,這時圆存,渲染引擎會為文字部分單獨創(chuàng)建一個圖層叼旋。
若出現(xiàn)滾動條,滾動條也會被創(chuàng)建單獨的圖層沦辙。
二夫植、圖層繪制
拿到了圖層樹,需要進行具體的繪制油讯。怎么做呢详民?
先要把每個圖層需要繪制的部分拆分成很多小的繪制指令,然后把這些指令按照順序組成一個待繪制列表
在這一階段陌兑,輸入的是圖層樹沈跨,輸出的是待繪制列表
三、柵格化操作
拆分為繪制指令后诀紊,就要進入真正的繪制工作了。
以上的步驟都是在渲染進程的主線程里進行的隅俘,而真正的繪制工作則是在合成線程里進行的邻奠。
上一步得到的待繪制列表,會被提交到合成線程为居,進行繪制碌宴。
合成線程如何繪制呢?
- 首先蒙畴,我們看到的網(wǎng)頁大多很長贰镣,需要拖動滾動條查看。實際上我們看到的網(wǎng)頁膳凝,只是一個視口(viewport)的大小碑隆。
- 所以,如果一次性將全部的網(wǎng)頁都繪制了蹬音,會耗費很多資源上煤,因為我一次性看不了那么多
- 因此,合成線程將圖層劃分為圖塊著淆,然后按照視口附近的圖塊優(yōu)先生成位圖劫狠。柵格化指將圖塊轉(zhuǎn)換成位圖拴疤。
四、合成和顯示
當所有圖塊都被柵格化独泞,合成線程會發(fā)送指令給瀏覽器進程呐矾。瀏覽器進程會將頁面內(nèi)容繪制到內(nèi)存里,再將內(nèi)存顯示在屏幕上
至此懦砂,就渲染完成了