• 回流和重绘总结


    1.总结

    reflow(回流):对DOM树进行渲染,只要修改DOM或修改元素的形状大小,就会触发reflow。

    display显示/隐藏元素,显示时占据空间,隐藏时元素不占据空间,隐藏前后dom结构有发生变化,需要重新渲染。
    visibility显示/隐藏元素,显示时占据空间,隐藏时元素占据空间,隐藏前后dom结构未发生变化,不需要重新渲染。

    单纯改变字体颜色,背景只需要repaint(重绘),不需要reflow。

    会导致回流的操作:
    1.页面首次渲染
    2.浏览器窗口大小发生改变
    3.元素尺寸或位置发生改变
    4.元素内容变化(文字数量或图片大小等等)
    5.元素字体大小变化
    6.添加或者删除可见的DOM元素
    7.激活CSS伪类(例如::hover)
    8.查询某些属性或调用某些方法

    1.我们首先讲讲HTML渲染过程

    内容解释
    1.HTML parser:HTML解析器,其本质是将HTML文本解释成DOM tree。
    2.CSS parser:CSS解析器,其本质是讲DOM中各元素对象加入样式信息。
    3.JavaScript引擎:专门处理JavaScript脚本的虚拟机,其本质是解析JS代码并且把逻辑(HTML和CSS的操作)应用到布局中,从而按程序要的要求呈现相应的结果
    4.DOM tree:文档对象模型树,也就是浏览器通过HTMLparser解析HTML页面生成的HTML树状结构以及相应的接口。
    5.render tree:渲染树,也就是浏览器引擎通过DOM Tree和CSS Rule Tree构建出来的一个树状结构,和dom tree不一样的是,它只有要最终呈现出来的内容,像或者带有display:none的节点是不存在render tree中的。
    6.layout:也叫reflow 重排,渲染中的一种行为。当rendertree中任一节点的几何尺寸发生改变了,render tree都会重新布局。
    7.repaint:重绘,渲染中的一种行为。render tree中任一元素样式属性(几何尺寸没改变)发生改变了,render tree都会重新画,比如字体颜色、背景等变化。

    解析HTML并构建DOM树,DOM 树包含了所有的 html 标签,包括不展示的 head 节点和 display:none 的节点,还有用JS动态添加的元素等。

    CSS标记则转换成CSS对象模型(CSSOM),CSSOM 树则会去掉浏览器不能识别的样式,比如不支持的浏览器前缀(chrome不支持的-moz-前缀)和 hack(如firefox不支持_开头的样式)。

    将 DOM 树和 CSSOM 树合并为 render 树,在这个过程中,需要计算每一个呈现对象的可视化属性,会去掉不展示在页面上的节点(如 display:none 和 head 节点等),因为这些节点不会用于呈现,而且不会影响呈现的,所以就不会包含到render tree中,但是visibility:hidden隐藏的元素还是会包含到render tree中的,因为visibility:hidden 会影响布局(layout),会占有空间。

    DOM Tree 和样式结构体组合后构建render tree, render tree类似于DOM tree,但区别很大,因为render tree能识别样式,render tree中每个NODE都有自己的style,而且render tree不包含隐藏的节点(比如display:none的节点,还有head节点),因为这些节点不会用于呈现,而且不会影响呈现的,所以就不会包含到 render tree中。

    然后是布局 render 树。render 树在创建完成时,并不包含位置和大小信息。计算这些值的过程称为布局或重排。从 render 树的根节点((对应于 HTML 文档的 元素))递归调用,计算每一个元素的位置和大小信息。

    最后使用 render 树绘制页面。在绘制阶段,系统会遍历 render 树,将其内容显示在屏幕上。

    3.那什么是回流?什么又是重绘呢?

    回流(Reflow):render 树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘。

    重绘:render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响 render 树重新布局的,比如修改字体颜色。

    他们的区别很大:
    1.回流必将引起重绘,而重绘不一定会引起回流。比如:只有颜色改变的时候就只会发生重绘而不会引起回流。
    2.当页面布局和几何属性改变时就需要回流,比如:添加或者删除可见的DOM元素,元素位置改变,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变。

    回流往往伴随着布局的变化,代价较大:

    重绘只是样式的变化,结构不会变化:

    浏览器的帮忙:

    所以我们能得知回流比重绘的代价要更高,回流的花销跟render tree有多少节点需要重新构建有关系
    因为这些机制的存在,所以浏览器会帮助我们优化这些操作,浏览器会维护1个队列,把所有会引起回流、重绘的操作放入这个队列,等队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会flush队列,进行一个批处理。这样就会让多次的回流、重绘变成一次回流重绘。

    4.应该尽量减少回流和重绘,那么怎样优化浏览器渲染过程?

    其实优化就是减少对render tree的操作,并减少对一些style信息的请求,尽量利用好浏览器的优化策略。

    1.不要1个1个改变元素的样式属性,最好直接改变className,但className是预先定义好的样式,不是动态的,如果你要动态改变一些样式,则使用cssText来改变

    2.DOM的增删行为
    让操作元素离线处理,即使用documentFragment或div等元素进行缓存操作,先把所有要添加到元素添加到1个div,最后才把这个div append到body中

    3.先display:none 隐藏元素,然后对该元素进行所有的操作,最后再显示该元素。因对display:none的元素进行操作不会引起回流、重绘。

    4.将引起回流的属性赋值给变量,进行缓存,需要用到的时候直接使用变量就行。例如获取一个元素的scrollTop、scrollLeft、scrollWidth、offsetTop、offsetLeft、offsetWidth、offsetHeight之类的属性,浏览器为了保证值的正确也会回流取得最新的值,所以如果你要多次操作,最取完做个缓存。

    5.减少操作影响的节点,影响的节点越多,则越消耗性能。

  • 相关阅读:
    在ASP.Net和IIS中删除不必要的HTTP响应头
    Json对象与Json字符串互转
    Jquery ajax传递复杂参数给WebService
    HTTP的KeepAlive是开启还是关闭?
    MQ产品比较-ActiveMQ-RocketMQ
    RocketMQ(7)——通信协议
    mq使用经验
    mq
    RocketMQ
    发送短信验证码实现方案
  • 原文地址:https://www.cnblogs.com/nianjiun99/p/10739980.html
Copyright © 2020-2023  润新知