美文网首页
渲染性能

渲染性能

作者: skoll | 来源:发表于2020-12-02 09:54 被阅读0次

    60fps 与设备刷新率

    1 .其中每个帧的预算时间仅比 16 毫秒多一点 (1 秒/ 60 = 16.66 毫秒)。但实际上,浏览器有整理工作要做,因此您的所有工作需要在 10 毫秒内完成。如果无法符合此预算,帧率将下降,并且内容会在屏幕上抖动。 此现象通常称为卡顿,会对用户体验产生负面影响

    渲染基本流程

    1 .JS :一般都是js操作,实现一些视觉变化效果
    2 .样式计算:根据匹配选择器,计算出哪些元素应用哪些css规则的过程,知道规则,将应用规则并计算每个元素的最终样式
    3 .布局:知道对一个元素应用哪些规则之后,浏览器即可以开始计算他要占用的空间大小和在屏幕中位置。网页的布局意味着一个元素可能会影响到其他元素,比如调整body的宽度就会影响到子元素的宽度以及树中各处节点。
    4 .绘制:绘制时填充像素的过程,设计文本,颜色,图像,边框和阴影,绘制一般实在多个层上面完成的
    5 .合成:由于页面的各个部分可能被分成多个层级,由此他们需要被正确按照顺序绘制到屏幕上,特别是对于重叠元素来说
    6 .但是并不是每次都走这个全部的过程

    7 . JS / CSS > 样式 > 布局 > 绘制 > 合成

    1 .如果您修改元素的“layout”属性,也就是改变了元素的几何属性(例如宽度、高度、左侧或顶部位置等),那么浏览器将必须检查所有其他元素,然后“自动重排”页面。任何受影响的部分都需要重新绘制,而且最终绘制的元素需进行合成
    

    8 .JS / CSS > 样式 > 绘制 > 合成

    1 .如果修改paint only 属性,背景图片,文字颜色或者阴影,不会影响页面布局的属性,浏览器就会跳过布局,直接执行绘制
    

    9 .JS / CSS > 样式 > 合成

    1 .如果修改一个既不需要布局,也不需要绘制的属性,浏览器只会执行合成
    2 .这个适合应用生命周期中的高压力点,比如动画或者滚动
    3 .https://csstriggers.com/ 
    4 .属性触发影响的部分
    

    1 .优化js执行

    1 .对于动画效果的实现,避免使用setTimeout,setInterval,要使用requestAnimationFrame
    2 .将长时间运行的js从主线程移到web worker
    3 .使用微服务来执行对多个帧的DOM更改
    4 .使用chrome的性能工具来评估代码

    requestAnimationFrame来实现视觉变化

    1 .保证js在帧开始的时候运行的唯一办法就是使用requestAnimationFrame。相当于一个钩子函数
    2 .框架或示例可能使用 setTimeout 或 setInterval 来执行动画之类的视觉变化,但这种做法的问题是,回调将在帧中的某个时点运行,可能刚好在末尾,而这可能经常会使我们丢失帧,导致卡顿

    降低复杂性或者使用web worker

    1 .JavaScript 在浏览器的主线程上运行,恰好与样式计算、布局以及许多情况下的绘制一起运行。如果 JavaScript 运行时间过长,就会阻塞这些其他工作,可能导致帧丢失
    2 .在许多情况下,可以将纯计算工作移到web worker,这些计算不需要访问DOM,仅仅是数据便利,搜索或者排序,加载和生成模型也可以
    3 .

    2 缩小样式计算的范围并降低复杂性

    1 .用于计算某元素计算样式的时间中大约有 50% 用来匹配选择器,而另一半时间用于从匹配的规则中构建 RenderStyle(计算样式的表示)
    2 .降低选择器的复杂性,最好只有一个 .box:nth-last-child(-n+1) .title {
    /* styles */
    } 避免这样的
    3 .BEM方式组织样式

    3 避免大型,复杂的布局和布局抖动

    1 .布局是浏览器计算各元素几何信息的过程。元素的大小以及在页面中的位置,根据所用的css,元素的内容或者父级元素每个元素都将有显式或者隐含的大小信息
    2 .主要有一下元素影响性能
    3 .需要布局的元素的数量,布局的复杂度

    尽可能避免布局操作

    1 .布局几乎总是作用到整个文档,如果有大量元素,将需要很长时间来计算所有元素的位置和尺寸
    2 .新的flex布局会显著减少布局的时间
    3 .

    避免强制同步布局

    1 .先读取样式值,然后进行样式更改
    2 .如果先进行样式更改,在读取的时候,会打乱本来的渲染顺序
    3 .js在运行 的时候,来自上一帧的旧布局的值是知道的。

    function logBoxHeight() {
    
      box.classList.add('super-big');
      //先改变了样式
      
      console.log(box.offsetHeight);
    //然后再求他的值,就会打乱顺序,浏览器必须先使用新的样式,然后再进行布局,最后返回新的高度。但是这是不必要的
    }
    

    4 .因此,始终应该批量读取样式,然后执行任何写的操作

    function logBoxHeight() {
      // Gets the height of the box in pixels
      // and logs it out.
      console.log(box.offsetHeight);
    
      box.classList.add('super-big');
    }
    

    5 .大多数情况,不需要应用样式然后查询,使用上一帧的值就足够了

    function resizeAllParagraphsToMatchBlockWidth() {
    
      // Puts the browser into a read-write-read-write cycle.
      for (var i = 0; i < paragraphs.length; i++) {
        paragraphs[i].style.width = box.offsetWidth + 'px';
    //这里其实更加糟糕,每次都会进行强制布局。
    需要把这个缓存起来
      }
    }
    
    //正确写法
    var width = box.offsetWidth;
    
    function resizeAllParagraphsToMatchBlockWidth() {
      for (var i = 0; i < paragraphs.length; i++) {
        // Now write.
        paragraphs[i].style.width = width + 'px';
      }
    }
    

    5 简化绘制的复杂度,减小绘制区域

    1 .绘制是填充像素的过程,像素最终合成到用户的屏幕上。是执行时间最长的任务。
    2 .除transform,opacity属性之外,更改任何属性都会触发绘制
    3 .可以通过提升层和动画的编排来减少绘制区域
    4 .Show paint rectangles
    5 .每次调试,感觉不应该发生绘制的地方发生了绘制,那就是问题,每次绘制部分都会闪烁绿色
    6 .常见新层的最佳方式就是will-change属性

    .moving-element {
      will-change: transform;
    }
    
    //不支持的情况
    .moving-element {
      transform: translateZ(0);
    }
    

    7 .层也有开销,不要再不分析的情况下提升元素
    8 .尽可能的避免绘制的发生,特别是在动画效果中。因为每帧 10 毫秒的时间预算一般来说是不足以完成绘制工作的,尤其是在移动设备上。

    6 坚持仅合成器的属性和管理层计数

    1 .react router最新的react router

    使输入处理程序去除抖动

    1 .输入处理程序可能是应用最容易出现性能的问题,因为他们可能阻止帧完成,并导致额外且不必要的布局工作
    2 .避免长时间运行输入处理程序,他们可能阻止滚动
    3 .不要再输入处理程序种进行样式更改
    4 .使用处理层序去除抖动,存储事件值在下一个requestAnimationFrame回调中处理样式更改
    5 .如果您附加一个输入处理程序,例如 touchstart、touchmove 或 touchend,则合成器线程必须等待此处理程序执行完成,因为您可能选择调用 preventDefault() 并且会阻止触摸滚动发生。即使没有调用 preventDefault(),合成器也必须等待,这样用户滚动会被阻止,这就可能导致卡顿和漏掉帧。确保您运行的任何输入处理程序应快速执行,并且允许合成器执行其工作
    6 .感觉这里遇到最复杂的就是虚拟列表了,每次滚动都需要做计算
    7 .使滚动处理程序去除抖动

    function onScroll (evt) {
    
      // Store the scroll value for laterz.
      lastScrollY = window.scrollY;
    
      // Prevent multiple rAF callbacks.
      if (scheduledAnimationFrame)
        return;
    
      scheduledAnimationFrame = true;
      requestAnimationFrame(readAndUpdatePage);
    }
    
    window.addEventListener('scroll', onScroll);
    

    测试网页性能

    1 .https://developers.google.com/web/fundamentals/performance/audit

    相关文章

      网友评论

          本文标题:渲染性能

          本文链接:https://www.haomeiwen.com/subject/nonaiktx.html