瀏覽器渲染原理和性能優化

1. 渲染原理:

(1)處理HTML生成DOM樹

(2)處理CSS生成CSSDOM樹

(3 )將兩樹合併成render樹

(4 )對render樹進行佈局計算

(5)將render樹中的每一個節點繪製到屏幕上

細化分析:
1.瀏覽器把獲取到的html代碼解析成1個Dom樹,html中的每個標籤都是Dom樹中的1個節點,根節點就是我們常用的document對象(<html> tag),當然這裏包含用js動態創建的dom節點


2瀏覽器把所有樣式(主要包括Css和瀏覽器的默認樣式設置)解析成樣式結構體,在解析的過程中會去掉瀏覽器不能識別的樣式,生成CSSDOM樹


3.DOM tree和CSSDOM tree合併成render tree,render tree中每個node都有自己的style,而且render tree不包含隱藏的節點(比如display:none的節點,還有無樣式head節點),因爲這些節點不會用於呈現,而且不會影響呈現的,注意visillty:hiddedn隱藏的元素還是會包含到render tree中的,因爲vsibilt:hidden會影響佈局(ayout),會佔有空間。


4.render tree構建完畢之後根據樣式計算佈局,佈局階段的輸出結果稱爲“盒模型”( box model)。盒模型精確表達了窗口中每個元素的位置和大小,而且所有的相對的度量單位都被轉化成了屏幕上的絕對像索位置(根據css2的標準,render tree中的每個節點都稱爲box(Box dimensions---盒子模型) , box所有屬性:width,height,margin,padding,left,top,border等。)


5.將這些信息渲染爲屏幕上每個真實的像素點了。這個階段稱爲"繪製”, 或者“柵格化

2. 重繪、重排
(1 )我們計算它們在當前設備中準確的位置和尺寸。這正是佈局階段要做的的工作,該階段在英語中也被稱爲“迴流”( reflow),當render tree中的一部分(或全部)因爲元素的規模尺寸,佈局,隱藏等改變而需要重新構建。也會迴流(其實我覺得叫重新佈局更簡單明瞭些)。每個頁面至少需要一-次迴流,就是在頁面第一-次加載的時候。

(2)重繪(repaints )當render tree中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響佈局的,比如background-color.則就叫稱爲重繪。
(3)重繪,重排會影響性能, 在瀏覽器的performance(性能)下,刷新看執行時間

藍色:網絡通信和HTML解析

黃色: JavaScript執行

紫色:樣式計算和佈局,即重排

綠色:重繪

(4)觸發重排的方法:

以下這些屬性和方法需要返回最新的佈局信息,重新計算渲染樹,就會造成迴流,能發重排以返回正確的值。建議將他們合併到一起操作,可以減少迴流的次數。

這些屬性包括: 

offsetTop. offsetLeft. offsetWidth, offsetHeight ; scrolTopscrolleft. scrollWidth. scrollHeight ; dientTop. clientLeft. clientWidth、dientHeight ; getComputedStyleO、currentStyle( ).

提高網頁性能,就是要降低"重排"和"重繪"的頻率和成本,儘量少觸發重新渲染。

DOM變動和樣式變動,都會觸發重新渲染。但是,瀏覽器已經很智能了,會盡量把所有的變動集中在一起, 排成一一個隊列 

然後一次性執行,儘量避免多次重新渲染div.style.color = 'red';

      div.style.background='yellow';div.style.left = '10px';div.style.width = '20px';

      但是瀏覽器只會觸發一次重排和重繪。

      般來說,樣式的寫操作之後,如果有上面那些屬性的讀操作,都會引發瀏覽器立即重排,這種重排,不會形成之前隊列優化div.style.color= 'red';

      var height = div.offseHeight;div.style.height = height + 'px';

Bad :
      div.style.left = div.offsetLeft + 'px';div.style.top = div.offsetTop+ 'px';

重排重繪兩次

Good:

      Var left = div.offsetLeft + 'px';Var top = div.offsetTop+ 'px';div.style.left = left;div.style.top = top;

      放到隊列一次執行重排重繪一次

      我們來測試一下js動態添加10000個li不同顏色而且設置寬度所耗費renderpainting的時間吧

      (5)理論上的解決優化辦法:

      1.DOM的多個讀操作(或多個寫操作), 應該放在一起。 不要兩個讀操作之間,加入一個寫操作。
      2.離線操作DOM如使用隱藏元素documentcreateDocumentFagment()   cloneNode();
      3.修改樣式的時候添加類名,或次性添加到dom.style.cssText上等

3. 3D屬性可以提高性能

(1)儘可能的多用硬件能力,使用3D屬性來開啓GPU加速,前提是用戶電腦性能較好,因爲3D效果會消耗更多的內存。

-webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
-webkit-transform: rotate3d(1,1,1,30deg);
-moz-transform: rotate3d(1,1,1,30deg);
-ms-transform: rotate3d(1,1,1,30deg);
transform: rotate3d(1,1,1,30deg);

(2)注意:如果動畫過程中有閃爍現象,常出現在動畫開始的時候,可以嘗試下面的hack方法:測試出來的方法

            -webkit-backface-visibility: hidden;
            -moz-backface-visibility: hidden;
            -ms-backface-bisibility: hidden;
            backface-visibility: hidden;
            -webkit-perspective: 1000;
            -moz-perspective: 1000;
            -ms-perspective: 1000;
            perspective: 1000;

(3)還有比如:transform:translate3d()移動效果的流暢度,遠高於任性形式下的left屬性值變化(animation,transition,JavaScript定時器等)

(4)儘可能的避免使用box-shadow陰影和gradients漸變,這個兩個屬性是頁面性能殺手

(5)儘可能的讓動畫元素不在文檔流中,及減少重排

position:fixed;

position:absolute;

(6)優化DOM reflow

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章