DOM树 CSS树 渲染树 回流重绘

解析与加载

解析

DOM树

DOM树构建 -> html节点解析的过程
深度优先解析原则
DOM树的构建与css样式无关 设置display:none 也会构建

CSS树

CSS树 样式结构体
在构建CSS树时会把不兼容不实用不识别的样式去掉

渲染树

渲染树 renderTree
domTree + cssTree
渲染树构建完毕 -> 才会根据他开始进行页面的绘制
1.渲染树每个节点都有自己的样式
2.不包含display:none head html style title之类不需要绘制的节点
注意 visibility : hidden相对应的节点是包含在渲染树上的 影响布局
3.渲染树上的每一个节点都会被当成一个盒子 有宽高
具有内容填充 边距 边框 位置 大小 其他样式

加载

浏览器渲染引擎解析与加载是一个异步的过程
解析完毕并不说明页面加载完毕
节点的加载在当前节点解析完成之后执行

回流重绘

当js对页面的节点操作时 就会产生回流或者重绘
回流 又叫 重排 reflow
重绘 repaint
回流一定引起重绘
重绘不一定是回流产生的后续反应

回流

因为节点的尺寸 布局(位置) display:none block 这一些改变的时候 渲染树中的一部分或者全部 需要重新构建
这种现象就叫回流

回流的代价比重绘高 不仅要考虑回流次数 也要考虑节点规模
在body最后插入节点 仅仅影响最后 在body开头插入节点 它下面的所有节点都会有影响

新的浏览器与一种优化机制 看到有回流重绘的操作就放到一个队列种 当积攒到一定数量批量执行 减少回流重绘次数

一个页面至少有一次回流 只要构建renderTree就会产生回流 就算没有js在页面加载的时候也会形成一次回流
DOM操作消耗性能 原因就在回流上 DOM操作优化一切都是以减少回流次数(缓存 document.createDocumentFragment创建文档碎片)
引起回流的因素
1.DOM节点增加 删除
2.DOM节点位置变化
3.元素的尺寸 边距 填充 边框 宽高
4.DOM节点display显示与否
5.页面的渲染初始化
6.浏览器窗口尺寸变化 -> resize
7.向浏览器请求某些样式信息 (offset相关 scroll相关 client相关 width height getComputedStyle currentStyle)

使用添加类名的方式减少回流重绘
这样子是有三次回流四次重绘

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 100px;
        height: 100px;
        background-color: #000;
      }
    </style>
  </head>
  <body>
    <div></div>
    <script>
      var oDiv = document.getElementsByTagName('div')[0];
      oDiv.onmouseover = function () {
        this.style.width = '200px';
        this.style.height = '200px';
        this.style.backgroundColor = 'green';
        this.style.border = '1px solid red';
      };
    </script>
  </body>
</html>

优化方式(1) 一次回流重绘

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 100px;
        height: 100px;
        background-color: #000;
      }
      div.active {
        width: 200px;
        height: 200px;
        border: 1px solid red;
        background-color: green;
      }
    </style>
  </head>
  <body>
    <div></div>
    <script>
      var oDiv = document.getElementsByTagName('div')[0];
      oDiv.onmouseover = function () {
        this.className += ' active';
      };
    </script>
  </body>
</html>

优化方式(2) 一次回流重绘

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 100px;
        height: 100px;
        background-color: #000;
      }
      div.active {
        width: 200px;
        height: 200px;
        border: 1px solid red;
        background-color: green;
      }
    </style>
  </head>
  <body>
    <div></div>
    <script>
      var oDiv = document.getElementsByTagName('div')[0],
        width = 200,
        height = 200,
        backgroundColor = 'green',
        border = '1px solid red';

      oDiv.onmouseover = function () {
        this.style.cssText = `
      			width:${width}px;
      			height:${height}px;
      			background-color:${backgroundColor};
      			border:${border};
      		`;
      };
    </script>
  </body>
</html>

优化方式(3) 使用display:none display:block 包裹 二次回流重绘

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 100px;
        height: 100px;
        background-color: #000;
      }
    </style>
  </head>
  <body>
    <div></div>
    <script>
      var oDiv = document.getElementsByTagName('div')[0];
      oDiv.onmouseover = function () {
        this.style.display = 'none';
        this.style.width = '200px';
        this.style.height = '200px';
        this.style.backgroundColor = 'green';
        this.style.border = '1px solid red';
        this.style.display = 'block';
      };
    </script>
  </body>
</html>

操作动画元素一定要用绝对定位

重绘

回流时 浏览器会重新构建受影响部分的渲染树 只要渲染树一被改变或者重新构建 就一定会引起重绘
回流完成后 浏览器会根据新的渲染树重新绘制回流影响的部分或全部节点 这个重新绘制的过程 就叫重绘

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_聪明勇敢有力气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值