移动端 像素渲染流水线与GPU Hack
什么是 像素渲染流水線
web頁面你所寫的頁面代碼是如何被轉換成屏幕上顯示的像素的。這個轉換過程可以歸納為這樣的一個流水線,包含五個關鍵步驟;
1.JavaScript:一般來說,我們會使用JavaScript來實現一些視覺變化的效果。比如用jQuery的animate函數做一個動畫、對一個數據集進行排序、或者往頁面里添加一些DOM元素等。
當然,除了JavaScript,還有其他一些常用方法也可以實現視覺變化效果,比如:CSS Animations, Transitions和Web Animation API。
2.計算樣式:這個過程是根據CSS選擇器,比如.headline或.nav > .nav_item,對每個DOM元素匹配對應的CSS樣式。這一步結束之后,就確定了每個DOM元素上該應用什么CSS樣式規
3.布局: ?上一步確定了每個DOM元素的樣式規則,這一步就是具體計算每個DOM元素最終在屏幕上顯示的大小和位置。web頁面中元素的布局是相對的,因此一個元素的布局發生變化,會聯動地引發其他元素的布局發生變化。比如,<body>元素的寬度的變化會影響其子元素的寬度,其子元素寬度的變化也會繼續對其孫子元素產生影響。因此對于瀏覽器來說,布局過程是經常發生的。
4.繪制: ?本質上就是填充像素的過程。包括繪制文字、顏色、圖像、邊框和陰影等,也就是一個DOM元素所有的可視效果。一般來說,這個繪制過程是在多個層上完成的。
5.渲染層合并:由上一步可知,對頁面中DOM元素的繪制是在多個層上進行的。在每個層上完成繪制過程之后,瀏覽器會將所有層按照合理的順序合并成一個圖層,然后顯示在屏幕上。對于有位置重疊的元素的頁面,這個過程尤其重要,因為一旦圖層的合并順序出錯,將會導致元素顯示異常。
雖然在理論上,頁面的每一幀都是經過上述的流水線處理之后渲染出來的,但并不意味著頁面每一幀的渲染都需要經過上述五個步驟的處理。實際上,對視覺變化效果的一個幀的渲染,有這么三種 常用的 流水線:
?1. JS / CSS > 計算樣式 > 布局 > 繪制 > 渲染層合并
如果你修改一個DOM元素的”layout”屬性,也就是改變了元素的樣式(比如寬度、高度或者位置等),那么瀏覽器會檢查哪些元素需要重新布局,然后對頁面激發一個reflow過程完成重新布局。被reflow的元素,接下來也會激發繪制過程,最后激發渲染層合并過程,生成最后的畫面。
?
?
?
?2. JS / CSS > 計算樣式 > 繪制 > 渲染層合并
如果你修改一個DOM元素的“paint only”屬性,比如背景圖片、文字顏色或陰影等,這些屬性不會影響頁面的布局,因此瀏覽器會在完成樣式計算之后,跳過布局過程,只做繪制和渲染層合并過程。
?
?
?
3. JS / CSS > 計算樣式 > 渲染層合并
如果你修改一個非樣式且非繪制的CSS屬性,那么瀏覽器會在完成樣式計算之后,跳過布局和繪制的過程,直接做渲染層合并。
第三種方式在性能上是最理想的,對于動畫和滾動這種負荷很重的渲染,我們要爭取使用第三種渲染流程(充分合理 利用 GPU hack)
?
?
下面我們先看個gif例子;4個dom元素運動;
第1個 left的,單純left運動 ? ? ? 綠色 差的
第2個 left的,left+gpu運動 ? ?
第3個 left的,單純translateX運動 ? 綠色差的
第4個 left的,單純translate3d運動(自動緩存GPU)
綠色部分(第一個 和 第三個 )表示dom 元素在運動時候,元素dom位置發生改變,促發了回流, (回流(也叫重排reflows)必將引起重繪(repaints),而重繪不一定會引起回流。)
?
相關css
#btn{ width:100%; margin:30px auto 300px; border:2px solid red; background:url(../loveImg/30939_1240374_248286.jpg) no-repeat center top; background-size:100% ; height:380px; position:relative; text-align:center;}#moveleft{ position:absolute; top:10px; left:0; background:#fff; color:#333; width:120px; height:60px;line-height:60px; text-align:center; }#moveleft2{ position:absolute; top:100px; left:0; background:#fff; color:#333; width:120px; height:60px;line-height:60px; text-align:center; }#movetranslateX{position:absolute; top:190px; left:0; background:#fff; color:#333;width:120px; height:60px; line-height:60px; text-align:center;}#movetranslate3D{position:absolute; top:280px; left:0; background:#fff; color:#333;width:120px; height:60px; line-height:60px; text-align:center;} .GPU{ -webkit-transform:translateZ(0);transform:translateZ(0);backface-visibility:hidden; }?
相關dom
<div id="btn"><div id="moveleft" >left</div><div id="moveleft2" class="GPU">GPU left</div><div id="movetranslateX">translateX</div><div id="movetranslate3D">movetranslate3D</div></div>
相關js
<script>var btn=document.getElementById("btn");var moveleft=document.getElementById("moveleft");var moveleft2=document.getElementById("moveleft2");var movetranslateX=document.getElementById("movetranslateX");var movetranslate3D=document.getElementById("movetranslate3D"); var isBACK=true;btn.addEventListener("click",function(){if(isBACK){transform(moveleft,{"left":"420px"},400);transform(moveleft2,{"left":"420px"},400);transform(movetranslateX,{"translateX":"420px"},400);transform(movetranslate3D,{"translate3d":"420px,0,0"},400);}else{transform(moveleft,{"left":"0"},400);transform(moveleft2,{"left":"0"},400);transform(movetranslateX,{"translateX":"0"},400);transform(movetranslate3D,{"translate3d":"0,0,0"},400); }isBACK=!isBACK;},!0);</script>?
?
回流何時發生:
當頁面布局和幾何屬性改變時就需要回流。下述情況會發生瀏覽器回流:
1、添加或者刪除可見的DOM元素;
2、元素位置改變;
3、元素尺寸改變——邊距、填充、邊框、寬度和高度
4、內容改變——比如文本改變或者圖片大小改變而引起的計算值寬度和高度改變;
5、頁面渲染初始化;
6、瀏覽器窗口尺寸改變——resize事件發生時;
?
?開啟 一般這樣可以了
.GPU{ -webkit-transform:translateZ(0);transform:translateZ(0);backface-visibility:hidden; }下面的css屬性也可以的 都能開啟GPU加速;
-webkit-transform: translate3d(0,0,0); -webkit-transform:translate3D(0,0,0); //大寫3D-webkit-transform: translateZ(0); -webkit-backface-visibility:hidden; -webkit-transform: scaleZ(0) ; -webkit-transform: rotateX(0); -webkit-transform: rotateY(0); -webkit-transform: rotateZ(0) ; -webkit-transform: scale3d(0,0,0) ; -webkit-transform: rotate3d(0,0,0,0);?
GPU hcak 緩存到渲染層;常用的環境 適當利用?
?1.含有 fixed 元素
?2.含有 動畫的元素
?3.含有?-webkit-overflow-scrolling: touch;
?
頁面中 transform() js?函數 代碼
?
參考與推薦:
?html5rocks
?google 開發者
騰訊舜子 16.6毫秒的優化 雖然是2013年的,還是很值得借鑒的和細細品讀的
阿里 hugohua 和荔枝 寫的 移動端性能調優
轉載于:https://www.cnblogs.com/surfaces/p/5235724.html
總結
以上是生活随笔為你收集整理的移动端 像素渲染流水线与GPU Hack的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Android]动态加载/热部署框架汇
- 下一篇: 36.迷宫(广度优先搜索)