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