当渲染树中部分或者全部元素的尺寸、结构或者属性发生变化时, 浏览器会重新渲染部分或全部文档的过程就称为回流。
当页面中某些元素样式发生变化, 但是不会影响其在文档流中的位置时, 浏览器就会对元素进行重新绘制的过程就称为重绘。
触发回流:
CSS 伪类DOM 元素在触发回流(重排)的时候, 由于浏览器渲染页面是基于流式布局的, 所以当触发回流时, 会导致周围的 DOM 元素重新排列, 它影响范围有两种:
全局范围: 从根节点开始, 对整个渲染树进行重新布局
局部范围: 对渲染树某部分或一个渲染对象进行重新布局
触发重绘:
colorbackground 相关属性:
background-colorbackground-image 等outline 相关属性:
outline-coloroutline-widthtext-decorationborder-radiusvisibilitybox-shadow注意: 当触发回流时, 一定会触发重绘, 但是重绘不一定会引发回流。
DOM 时, 尽量在低层级的 DOM 节点进行操作table 布局, 一个小改动可能使整个 table 进行重新布局CSS 的表达式absolute 或 fixed, 使元素脱离文档流, 这样他们发生变化就不会影响其他元素DOM, 可以创建一个文档片段 documentFragment, 在它上面应用所有 DOM 操作, 最后再把它添加到文档中display: none, 操作结束后再把它显示出来。因为在 display 属性为 none 的元素上进行的 DOM 操作不会引发回流和重绘DOM 的多个读操作(或写操作)放在一起, 而不是读写操作穿插着写。这得益于浏览器的渲染队列机制浏览器针对页面的回流与重绘, 进行了自身的优化——渲染队列。
浏览器会将所有的回流、重绘操作放在一个队列中, 当队列中的操作到了一定的数量或到了一定的时间间隔, 浏览器就会对队列进行批处理。这样就会让多次的回流、重绘变成一次回流重绘。
上面, 将多个读操作(或者写操作)放在一起, 就会等所有的读操作进入队列之后执行, 这样, 原本应该是触发多次回流, 变成了只触发一次回流。
对于如何优化动画, 一般情况下, 动画需要频繁的操作 DOM, 会导致页面性能问题, 我们可将动画的 position 属性设置为 absolute 或 fixed, 将动画脱离文档流, 这样他的回流就不会影响到页面了。
文档片段接口, 一个没有父对象的最小文档对象。它被作为一个轻量版的 Document 使用, 就像标准的 document 一样, 存储由节点(nodes)组成的文档结构。与 document 相比, 区别是 DocumentFragment 不是真实 DOM 树的一部分, 它的变化不会触发 DOM 树重新渲染, 不会导致性能等问题。
当我们把一个 DocumentFragment 节点插入文档树时, 插入的不是 DocumentFragment 自身, 而是它的所有子孙节点。在频繁 DOM 操作时, 就可以将 DOM 元素插入 DocumentFragment, 之后一次性将所有的子孙节点插入文档中。和直接操作 DOM 相比, 将 DocumentFragment 节点插入 DOM 树时, 不会触发页面重绘, 这样就大大提高了页面性能。