zoukankan      html  css  js  c++  java
  • 移动端 像素渲染流水线与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{ 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; 120px; height:60px;line-height:60px;  text-align:center; }
     #moveleft2{ position:absolute; top:100px; left:0; background:#fff; color:#333; 120px; height:60px;line-height:60px;  text-align:center; }
     #movetranslateX{position:absolute; top:190px; left:0; background:#fff; color:#333;120px; height:60px; line-height:60px; text-align:center;}
     #movetranslate3D{position:absolute; top:280px; left:0; background:#fff; color:#333;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 和荔枝 写的 移动端性能调优

  • 相关阅读:
    浅析影响一个网站的因素
    23种常用设计模式的UML类图
    各版本IE兼容问题,IE6,IE7,IE8,IE9,IE10,IE11
    47种常见的浏览器兼容性问题大汇总
    5个Sublime Text 的插件推荐
    网页设计师神器,快速生成网站配色、字型等风格的工具——Stylify Me
    免费的高分辨率图库——re:splashed 可用做网页背景、设计或桌面壁纸
    MySQL(18):Select- subquery子查询
    MySQL(17):Select-union(联合查询)使用注意事项
    MySQL(16):Select-union(联合查询)
  • 原文地址:https://www.cnblogs.com/surfaces/p/5235724.html
Copyright © 2011-2022 走看看