• 重绘(Repaint)和回流(Reflow)(重排),以及如何优化?


    1、浏览器渲染机制

    1. 浏览器采用流式布局模型;
    2. 浏览器会把HTML解析成DOM树,解析css构建render树(将css解析成树形的数据结构,然后结合DOM合并成render树)
    3. 有了RenderTree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制带页面上
    4. 由于浏览器使用流式布局,对RenderTree的计算同城只需要遍历一次就可以完成,但table及内部元素除外,他们可能需要多次计算,通常需要花3倍于同等元素的时间,这也是为什么要避免使用table布局的原因之一。

    2、重绘

    由于节点的几何属性发送改变或者由于样式发送改变而不会影响布局的,称为重绘。例如outline,visibility,color,bacjground-color等,重绘的代价是高昂的,因为浏览器必须验证DOM树上其他节点元素的可见性。

    3、回流(重排)

    回流就是布局或者集合属性需要改变就称为回流。回流是影响浏览器性能的关键因素,因为其变化涉及到部分页面(整个页面)的布局更新,一个元素的回流可能会导致了其所有子元素以及DOM中紧随其后的节点、祖先节点元素的随后的回流。因为其在DOM中回流元素之后,大部分回流将导致页面的重新渲染,回流必定会发生重绘,重绘不一定会引发回流。

    下面这些操作会导致回流:

    1. 页面的首次渲染
    2. 浏览器的窗口大小发生变化
    3. 元素的内容发生变化
    4. 激活css伪类
    5. 查询某些属性或者调用某些方法
    6. 添加或者删除可见的DOM元素

    4、浏览器优化

    现在浏览器大多都是通过队列机制来批量更新布局,浏览器会把修改操作放在队列中,至少一个浏览器刷新才会清空队列,但是当你获取布局信息的时候,比如改变元素的高度,元素的位置,导致浏览器不得不重新计算与元素的几何属性,队列中可能会有影响这些属性或方法值的操作,即使没有,浏览器也会强制清空队列,触发回流与重绘来确保返回正确的值并重新构建渲染树。

    主要包括以下属性或方法:

    1. offsetTop、offsetLeft、offsetWidth、offsetHeight
    2. scrollTop、scrollLeft、scrollWidth、scrollHeight
    3. clientTop、clientTlLeft、clientTWidth、clientTHeight
    4. width、height
    5. getComputedStyle()
    6. getBoundingClientRect()

    所以我们应该避免频繁的使用上述的属性,它们斗湖强制渲染刷新队列

    5、减少重绘与回流

    1. css
    • 使用tarnsform替代top
    • 使visibility替换dispaly:none。因为前者只会引起重绘,后者会引起回流。
    • 避免使用table布局,可能很小的一个改动会造成整个table的重新布局
    • 尽可能在DOM树的最末端改变class,回流是不可避免的,但是可以减少其影响,尽可能在DOM树的最末端改变class,可以限制了回流的范围,使其影响尽可能少的节点。
    • 避免设置多层内联样式,css选中符从右往左匹配查找,避免节点层级过多,保证层级扁平。
    • 将动画效果应用到position属性为absolute或者fixed元素上,避免影响其他元素的布局,这样只是一个重绘,而不是回流,同时,控制动画速度可以选中requestAnimationFrame.
    • 避免使用css表达式,可能会引起回流
    • css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘。但是对于动画的其他属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提高这些动画的性能
    1. js
    • 避免频繁操作样式,做好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性
    • 避免频繁操作DOM;可以创建一个documentFragment,在它上面应用所有DOM操作,最后把它添加到文档中
    • 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
    • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流
  • 相关阅读:
    mysql缓存、log、存储引擎、b+数解答
    Java EE企业级开发学习 -- day1
    Windows系统SVN SERVER迁移。从服务器A迁移到服务器B
    一文速通 css3 2D转换【内含开发常用效果实现】
    华为数字化转型之道 方法篇 第四章 用变革的方法确保规划落地
    【MATLAB教程案例1~10总结】通信类matlab仿真经验和技巧总结
    Kernel源码笔记之文件系统:2. fuse——挂载
    C# 日志框架Serilog使用
    外国电影字幕翻译,怎么把英文字幕翻译成中文字幕?
    工程伦理--16.1传统制造业的转型升级与伦理问题
  • 原文地址:https://blog.csdn.net/fangqi20170515/article/details/126989725