首先是html渲染過程
解析html並構建dom樹和cssom樹,瀏覽器對html標記轉換成文件物件模型,css標記則轉換成css物件模型(cssom),dom 樹包含了所有的 html 標籤,包括不展示的 head 節點和 display:none 的節點,而 cssom 樹則會去掉瀏覽器不能識別的樣式,比如不支援的瀏覽器字首(chrome不支援的-moz-字首)和 hack(如firefox不支援_開頭的樣式)
接著就是構建render 樹。將 dom 樹和 cssom 樹合併為 render 樹,在這個過程中,需要計算每乙個呈現物件的視覺化屬性,會去掉不展示在頁面上的節點(如 display:none 和 head 節點等),因為這些節點不會用於呈現,而且不會影響呈現的,所以就不會包含到render tree中,但是visibility:hidden隱藏的元素還是會包含到render tree中的,因為visibility:hidden 會影響布局(layout),會占有空間。
然後是布局 render 樹。render 樹在建立完成時,並不包含位置和大小資訊。計算這些值的過程稱為布局或重排。從 render 樹的根節點((對應於 html 文件的 元素))遞迴呼叫,計算每乙個元素的位置和大小資訊。
最後使用 render 樹繪製頁面。在繪製階段,系統會遍歷 render 樹,將其內容顯示在螢幕上。
那麼什麼是回流,什麼又是重繪呢?
回流(reflow):render 樹中的一部分(或全部)因為元素的規模尺寸,布局,隱藏等改變而需要重新構建。回流的時候,瀏覽器會使渲染樹中受到影響的部分失效,並重新構造這部分渲染樹,完成回流後,瀏覽器會重新繪製受影響的部分到螢幕中,該過程稱為重繪。
重繪:render tree中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響 render 樹重新布局的,比如修改字型顏色
那麼什麼情況下會產生回流呢?
1. 改變 dom 樹結構,比如新增或者刪除可見的元素、改變文字內容、改變位置
2. 改變元素幾何尺寸:邊距、填充、邊框、寬度和高度
3. 改變瀏覽器視窗尺寸
4. 偽類啟用,在使用者互動過程中發生
應該儘量減少回流和重繪,那麼怎樣優化瀏覽器渲染過程?
其實優化就是減少對render tree的操作,並減少對一些style資訊的請求,盡量利用好瀏覽器的優化策略。
1. 不要1個1個改變元素的樣式屬性,最好直接改變classname,但classname是預先定義好的樣式,不是動態的,如果你要動態改變一些樣式,則使用csstext來改變
2. 讓操作元素離線處理
先display:none 隱藏元素,然後對該元素進行所有的操作,最後再顯示該元素。因對display:none的元素進行操作不會引起回流、重繪。
3. 將引起回流的屬性賦值給變數,進行快取,需要用到的時候直接使用變數就行
4. 減少操作影響的節點,影響的節點越多,則越消耗效能。
參考:
重繪與回流
很多面試都會問到的問題,那麼說起這兩個概念,首先先了解一下,瀏覽器對乙個頁面對渲染過程。1.使用者輸入url位址,瀏覽器根據網域名稱查詢ip位址 2.瀏覽器向伺服器傳送http請求 3.伺服器接受請求,根據請求返回相應的html 返回給瀏覽器 4.瀏覽器接受到伺服器的相應結果,對頁面做解析渲染 1 ...
重繪與回流
dom樹結構變化 新增或者刪除可見的dom元素 元素幾何屬性發生變化 頁面渲染初始化 獲取某些屬性 瀏覽器視窗發生變化,即 resize事件發生 啟用css偽類 hover 改變元素顏色 改變元素背景色 將改變樣式的操作集合在一次完成,直接改變classname或csstext 讓要操作的元素進行離...
重繪與回流
css外部檔案的引入要放到頭部,載入css的時候頁面渲染是被阻塞的,js也是會阻塞頁面渲染的,ui渲染和js引擎執行緒是互斥的,不是並行的,css的效能會讓js變慢,優化效能,layout painting。當render tree中的一部分 或全部 因為元素的規模尺寸,幾何屬性,布局,隱藏等改變而...