zoukankan      html  css  js  c++  java
  • 避免无用的渲染绘制(Avoiding Unnecessary Paints)

    本文翻译自html5rock上的文章,文章英文原版地址在最后给出。

    文中的Paints我翻译成渲染绘制,我自己是这么理解。

    开始


     

    绘制(渲染)一个网站或者一个应用的元素对浏览器来说开销是很大的,它会对运行时的效率产生负面影响,在这篇文章中我们将快速的过一遍,哪些情况会导致导致绘制事件在浏览器中产生,以及如何在你今后的工作中尽量避免没必要的绘制。

     

    绘制(渲染):一场超快的旅行


    浏览器的主要任务之一就是将DOMCSS转换成像素并绘制到屏目上,这是一系列复杂的处理过程。浏览器先读取HTML标签并由此创建DOM树,它对CSS也是进行了类似的工作,读取CSS并创建CSSOM树,然后将两者合并,最终我们就可以根据合并后的结构渲染成像素到屏目了

     

    绘制过程本身就挺有趣。在Chrome浏览器中,合并后的DOM树与CSS树被一款名叫Skia的软件进行栅格化。如果你曾使用过CANVASAPI,那么你会觉得它们的API非常相似。

    不光是moveTo, lineTo等这些API,另外的一些高级API也一样非常相似。本质上来讲,所有需要被绘制的元素都将被提取到能被Skia执行的集合中,执行后输出的是一堆位图。这些位图将被上传到GPU中,GPU将帮他们组合在一起并最终输出到屏目上。

     

    Skia的工作量是直接受你在元素上所应用的样式引响的。如果你在元素应用的样式算法很复杂那么,会大大加重Skia的工作。你可以参考这篇文章article on how CSS affects page render weight,以更深的理解CSS如何影响页面渲染。

     

    总而言之,绘制工作费时间,如果我们不减少绘制,那么可能会掉侦。用户可能会注意到掉帧,看起来会闪一下。这对于我们的APP上来说是从根本上伤害了用户体验。我们不希望看到这样的结果吧,so让我们来看看哪些东西会产生必要的绘制(渲染)工作,以及我们能对这些做些啥优化。

     

    Scrolling(滚动)


    无论你是往上还是往下滚动,内容在显示到屏目上之前浏览器都需要进行重绘。如果一切顺利的话,可能产生重绘的区域会是很小一块,但是即使是很小一块,那一小块元素可能就是应用了复杂的CSS样式。所以不会因为绘制的区域小而绘制的速度会快。

    为了看清哪些区域被重绘了,你可以使用Chrome中自带的调试工具,点击右上角的设置按钮,选中 “Show Paint Rectangles后,在你的页面中做一些简单的交互,你便会看到一些会闪动的矩形框,那就是重绘的区域了。

     

    滚动的性能表现,是你网站成功的关键。用户真的会关心你的站点或应用滚动的是不是顺畅,他们可不会喜欢滚动的不流畅的网站。我们在滚动时保证轻量的绘制工作,因此而得到的一个好处就是用户看不到闪动或掉帧这类事情了。

     

    我之前已经写过一篇文章是关于滚动性能的,如果你想了解更我,可以参考这篇文章 article on scrolling performance

    Interactions(交互)


    交互是另一个产生绘制工作的原因,如:hovers, click,touches drags无论用户执行了其中的哪一样操作都会引发绘制或重绘。让我们以hover举个栗子,当hover某个元素时,Chrome不得不重绘那个被hover影响的元素。如果滚动时有一个很大很复杂的重绘工作,那么你将会看到绘制帧频的下降。

     

    大家都想要好的、流畅的交互动画,这咱又得关心一下动画样式在变化时的花费时间及性能成本

    An unfortunate combination(不幸的组合)


    当我滚动的同时移动鼠标时会发生什么 ?在无意中是完全有可能触发昂贵的重绘开销的,这将导致我的帧频率小于16.7ms(我们应该保持在每秒60帧的频率)。我已经写了一个demo来更直观的表达我所说的情况created a demo 希望你在滚动的同时移动鼠标能看到hover效果。但是让我们看看Chrome调试工具告诉了我们什么


     
     

    在上图中你可以看到,当我在某一个块元素上(blocks)上hover时调试工具已捕获了绘制工作。为了看效果,我在demo中疯狂的加重了样式效果(缩放,阴间等动画效果)。这导致帧频逼近或偶尔间超过了帧频的临界值。最后我想要的是减少不必要的绘制工作,尤其是在滚动时。

    我们如何实现呢,实现其实很简单,技巧是添加一个scroll回调handler处理函数,在这个函数内禁止hover效果,同时设置一个计时器,用以恢复hover效果。这意谓着我们保证在滚动时禁止一些开销昂贵的交互效果,并且在停止滚动足够的时间后恢复那些效果

     

    实际应用时注意!

    改变此项会影响你应用程序用户体验,所以明智的对待它,延时恢复效果要在你和的团队能接受的时间范围内


     

    这是对应的代码

    // Used to track the enabling of hover effects
    var enableTimer = 0;
    
    /*
     * Listen for a scroll and use that to remove
     * the possibility of hover effects
     */
    window.addEventListener('scroll', function() {
      clearTimeout(enableTimer);
      removeHoverClass();
    
      // enable after 1 second, choose your own value here!
      enableTimer = setTimeout(addHoverClass, 1000);
    }, false);
    
    /**
     * Removes the hover class from the body. Hover styles
     * are reliant on this class being present
     */
    function removeHoverClass() {
      document.body.classList.remove('hover');
    }
    
    /**
     * Adds the hover class to the body. Hover styles
     * are reliant on this class being present
     */
    function addHoverClass() {
      document.body.classList.add('hover');
    }

    如你所见,我们用了一个class来决定hover效果是否被允许使用,下面就是这个classcss表达式

     

    /* Expect the hover class to be on the body
     before doing any hover effects */
    .hover .block:hover {}

     

    这就是所有的内容了

    Conclusion(结束语)


    渲染的性能表现对于用户是否喜欢你的应用至关重要,你需要的是尽量保证绘制工作量保持在16ms帧频率以下,为了帮助实现这一目标,你得使调式工具一直贯穿于你的开发过程中,确保帧频保持在正常范围内,并随时修复上升的帧频。

     

    被忽略的交互过程,特别是重试绘制元素,是渲染性能的杀手,正如你所见,我们可以用一些简单的代码解决掉这些问题。

     

    看一看你的站点和应用,能不能做一些渲染绘制上面的优化

     

     

     

     

     

     


     

     

     

    本文翻译自:

    http://www.html5rocks.com/en/tutorials/speed/unnecessary-paints/

     

    我英文水平有限,凑合着翻,全当自我学习欢迎交流学习

     

    ========================================================

     

    转载处请注明:博客园(王二狗)willian12345@126.com

     

     

     

     

  • 相关阅读:
    CodeForces 660D Number of Parallelograms
    【POJ 1082】 Calendar Game
    【POJ 2352】 Stars
    【POJ 2481】 Cows
    【POJ 1733】 Parity Game
    【NOI 2002】 银河英雄传说
    【NOI 2015】 程序自动分析
    【POJ 1704】 Georgia and Bob
    【HDU 2176】 取(m堆)石子游戏
    【SDOI 2016】 排列计数
  • 原文地址:https://www.cnblogs.com/willian/p/3684704.html
Copyright © 2011-2022 走看看