css动画属性性能

   性能主要表现:流量、功耗与流畅度

在现有的前端动画体系中,通常有两种模式:JS动画与CSS3动画。 JS动画是通过JS动态改写样式实现动画能力的一种方案,在PC端兼容低端浏览器中不失为一种推荐方案。 而在移动端,我们选择性能更优浏览器原生实现方案:CSS3动画。

然而,CSS3动画在移动多终端设备场景下,相比PC会面对更多的性能问题,主要体现在动画的卡顿与闪烁。

   1,webkit-transform: translateX(3em) 使用优于left

  • CSS动画属性会触发整个页面的重排relayout、重绘repaint、重组recomposite
  • Paint通常是其中最花费性能的,尽可能避免使用触发paint的CSS动画属性,这也是为什么我们推荐在CSS动画中使用webkit-transform: translateX(3em)的方案代替使用left: 3em,因为left会额外触发layout与paint,而webkit-transform只触发整个页面composite
  • div {
      -webkit-animation-duration: 5s;
      -webkit-animation-name: move;
      -webkit-animation-iteration-count: infinite;
      -webkit-animation-direction: alternate;
       200px;
      height: 200px;
      margin: 100px;
      background-color: #808080;
      position: absolute;
    }
    @-webkit-keyframes move{
        from {
            left: 100px;
        }
        to {
            left: 200px;
        }
    }
    
    使用left将持续触发页面重绘,有闪烁
    @-webkit-keyframes move{
        from {
            -webkit-transform: translateX(100px);
        }
        to {
            -webkit-transform: translateX(200px);
        }
    }
    
    使用-webkit-transform页面只发生重组,效果好很多
    详情移步:https://github.com/AlloyTeam/Mars/blob/master/performance/css-property-animation-performance.md

    2,尽可能多的利用硬件能力,如使用3D变形来开启GPU加速

    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    -ms-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    如动画过程有闪烁(通常发生在动画开始的时候),可以尝试下面的Hack:
    
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    -ms-backface-visibility: hidden;
    backface-visibility: hidden;
    
    -webkit-perspective: 1000;
    -moz-perspective: 1000;
    -ms-perspective: 1000;
    perspective: 1000;
    如下面一个元素通过translate3d右移500px的动画流畅度会明显优于使用left属性:
    
    #ball-1 {
      transition: -webkit-transform .5s ease;
      -webkit-transform: translate3d(0, 0, 0);
    }
    #ball-1.slidein {
      -webkit-transform: translate3d(500px, 0, 0);
    }
    
    
    #ball-2 {
      transition: left .5s ease;
      left: 0;
    }
    #ball-2.slidein {
      left: 500px;
    }
    注:3D变形会消耗更多的内存与功耗,应确实有性能问题时才去使用它,兼在权衡

    3,尽可能少的使用box-shadowsgradients

    box-shadowsgradients往往都是页面的性能杀手,尤其是在一个元素同时都使用了它们,所以拥抱扁平化设计吧。

    4,尽可能的让动画元素不在文档流中,以减少重排

    position: fixed;
    position: absolute;

    5,优化 DOM layout 性能,减少渲染次数,示例如下:

    // 触发两次 layout
    var newWidth = aDiv.offsetWidth + 10;   // Read
    aDiv.style.width = newWidth + 'px';     // Write
    var newHeight = aDiv.offsetHeight + 10; // Read
    aDiv.style.height = newHeight + 'px';   // Write
    
    // 只触发一次 layout
    var newWidth = aDiv.offsetWidth + 10;   // Read
    var newHeight = aDiv.offsetHeight + 10; // Read
    aDiv.style.width = newWidth + 'px';     // Write
    aDiv.style.height = newHeight + 'px';   // Write

    详情移步:https://github.com/AlloyTeam/Mars/blob/master/performance/high-performance-css3-animation.md

    另外,附上腾讯移动Web前端知识库 

    https://github.com/AlloyTeam/Mars

    重点:iOS与Android平台上问题列表 

    https://github.com/AlloyTeam/Mars/tree/master/issues
    css3翻转动画实现
    http://www.tuicool.com/articles/MV3UvuA

    示例:左右翻转180度
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            /* entire container, keeps perspective */
            .flip-container {
                perspective: 1000;
            }
            /* flip the pane when hovered */
            .flip-container:hover .flipper, .flip-container.hover .flipper {
                transform: rotateY(180deg);
            }
    
            .flip-container, .front, .back {
                 320px;
                height: 480px;
            }
    
            /* flip speed goes here */
            .flipper {
                transition: 5s;
                transform-style: preserve-3d;
    
                position: relative;
            }
    
            /* hide back of pane during swap */
            .front, .back {
                backface-visibility: hidden;
                position: absolute;
                top: 0;
                left: 0;
            }
    
            /* front pane, placed above back */
            .front {
                z-index: 2;
                background-color: antiquewhite;
                -webkit-box-shadow:30px 30px 30px aquamarine;
            }
    
            /* back, initially hidden pane */
            .back {
                transform: rotateY(180deg);
                background-color: aqua;
            }
        </style>
    </head>
    <body>
    <div class="flip-container" ontouchstart="this.classList.toggle('hover');">
        <div class="flipper">
            <div class="front">
                1
                <!-- 前面内容 -->
            </div>
            <div class="back">
                2
                <!-- 背面内容 -->
            </div>
        </div>
    </div>
    </body>
    </html>
    
    
    
     


原文地址:https://www.cnblogs.com/weilantiankong/p/6170418.html