2017.11.24-学习笔记:页面的重绘与回流

1.页面呈现流程

  • 首先、浏览器会把获取到的 HTML 代码解析成一个 DOM 树,HTML 中的每个 tag(标签)都是 DOM 树中的一个节点,根节点就是我们常用的 document 对象。DOM 树里包含了所有 HTML 标签,包括 display:none,还有通过 JS 动态添加的元素。
  • 然后、浏览器会把所有样式(css)解析成样式结构体。
  • 关键、DOM 树和样式结构体组合后构建成 render tree(渲染树),rander tree 是 DOM 树的升级版,能识别样式,render tree 中的每个 node (节点)都有自己的 Style,而且 render tree不包含隐藏的节点(指不占位置的)。其中每个节点,理解页面元素为一个具有填充、边距、边框和位置的盒子。
  • 最后、一旦render tree 构建完毕,浏览器就可以根据 render tree 来绘制页面了。

2.回流与重绘

  • 回流:当 render tree 中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变二需要充新构建。
  • 每个页面至少需要一次回流,就是在页面第一次加载的时候。
  • 重绘:在回流的时候,浏览器会使 render tree 中受到影响的部分失效,并重新构造这部分 render tree,完成回流后,浏览器会重新绘制受影响的部分,这个过程叫做重绘。
  • 重绘发生在:当render tree 中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局
  • 注意:回流必将引起重绘,而重绘不一定会引起回流。

3.回流何时发生

当页面布局和几何属性(大小,位置)改变时就需要回流。

  • 1、添加或者删除可见的DOM元素;
  • 2、元素位置改变;
  • 3、元素尺寸改变——边距、填充、边框、宽度和高度
  • 4、内容改变——比如文本字体改变或者图片大小改变而引起的计算值宽度和高度改变;
  • 5、页面渲染初始化;
  • 6、浏览器窗口尺寸改变——resize事件发生时;

4.浏览器优化

  • js每操作一次样式,就会引起回流或者重绘,这样浏览器吃不消。
  • 然后浏览器就想了个办法,搞一个 队列,把所有会引起回流、重绘的操作放入这个队列里,等队列中的操作 到了一定的数量 或者 到了一定的时间间隔,浏览器就会 flush队列,像马桶一样冲一次,进行一个批处理。这样就会让多次回流、重绘变成一次回流重绘。
  • 因为这种优化,会发生一些问题,例如:
// 页面上一个按钮,一个盒子
// 需求:点击按钮,让盒子先往右,再往下
btn.onclick = function () {
  box.style.transition = 'none';
  box.style.transform = 'translateX(800px)';

  box.style.transition = 'transform 1s';
  box.style.transform = 'translate(800px,300px)';
}
// 盒子直接斜着跑过去了,因为队列未处理

手动强制 flush 队列:

btn.onclick = function () {
  box.style.transition = 'none';
  box.style.transform = 'translateX(800px)';

  box.offsetWidth; ==> 手动刷新队列

  box.style.transition = 'transform 1s';
  box.style.transform = 'translate(800px,300px)';
}
// 盒子就先往右,再往下了

或者放到异步队列中:

btn.onclick = function () {
  box.style.transition = 'none';
  box.style.transform = 'translateX(800px)';

  setTimeout(function () {
    box.style.transition = 'transform 1s';
    box.style.transform = 'translate(800px,300px)';
  }, -1)
}
// 同样,盒子会先往右,再往下。
  • 所以有时候我们需要自己手动刷新队列,让浏览器的优化不起作用。

5.手动刷新队列

  • 当你向浏览器请求一些 Style 信息的时候,就会让浏览器 flush 队列
      1. offsetTop, offsetLeft, offsetWidth, offsetHeight
      1. scrollTop/Left/Width/Height
      1. clientTop/Left/Width/Height
      1. width,height
      1. 请求了getComputedStyle(), 或者 IE的 currentStyle

6.如何减少回流、重绘

  • 1.直接改变className,如果动态改变样式,则使用cssText(考虑没有优化的浏览器)
  • 2.让要操作的元素进行”离线处理”,处理完后一起更新
  • 3.不要经常访问会引起浏览器flush队列的属性,如果你确实要访问,利用缓存
  • 4.让元素脱离动画流,减少回流的Render Tree的规模

参考文档:《页面重绘和回流以及优化》


Knowledge changes the mind



2017.11.24-学习笔记:页面的重绘与回流_第1张图片

你可能感兴趣的:(2017.11.24-学习笔记:页面的重绘与回流)