参考自 (MDN).javascript
构建渲染树,浏览器须要作一下工做:java
第一步遍历节点的时候,须要知道什么节点是不可见的。web
注意: 渲染树只包含可见的节点浏览器
当 Render Tree
中部分或所有, 因元素的尺寸、布局、隐藏等改变而须要从新构建,浏览器从新渲染的过程称为 回流。缓存
会致使回流的操做:函数
DOM
元素。CSS
伪类 (eg: :hover
)。一些经常使用且会致使回流的属性和方法。布局
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
scrollIntoView()
、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
当页面中元素样式的改变并不影响b布局时(eg:color
、background-color
等),浏览器会将新样式赋予给元素并从新绘制它,这个过程称为重绘。性能
一句话: 回流必将引发重绘,重绘不必定会引发回流。字体
有时即便仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。优化
现代浏览器会对频繁的回流或重绘操做进行优化:
浏览器会维护一个队列,把全部引发回流和重绘的操做放入队列中,若是队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样能够把屡次回流和重绘变成一次。
当你访问如下属性或方法时,浏览器会马上清空队列:
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
scrollIntoView()
、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
由于队列中可能会有影响到这些属性或方法返回值的操做,即便你但愿获取的信息与队列中操做引起的改变无关,浏览器也会强行清空队列,确保你拿到的值是最精确的。
table
布局 (尽可能不要使用表格布局,若是没有定宽表格一列的宽度由最宽的一列决定,那么极可能在最后一行的宽度超出以前的列宽,引发总体回流形成table可能须要屡次计算才能肯定好其在渲染树中节点的属性,一般要花3倍于同等元素的时间。)// bad
for (var i = 0; i < len; i++) {
el.style.left = el.offsetLeft + x + "px";
el.style.top = el.offsetTop + y + "px";
}
// good
var x = el.offsetLeft,
y = el.offsetTop;
for (var i = 0; i < len; i++) {
x += 10;
y += 10;
el.style = x + "px";
el.style = y + "px";
}
复制代码
let box = document.getElementById("box").style;
// bad
box.color = "red"; // 重绘
box.size = "14px"; // 回流、重绘
// good
box.bord = '1px solid red'
复制代码
DOM
,建立一个documentFragment
,在它上面应用全部 DOM
操做,最后再把它添加到文档中。DocumentFragment,文档片断接口,表示一个没有父级文件的最小文档对象. 与 Document
最大的区别是由于 DocumentFragment
不是真实 DOM
树的一部分,它的变化不会触发 DOM
树的(从新渲染) ,且不会致使性能等问题。
可使用 document.createDocumentFragment
方法或者构造函数来建立一个空的 DocumentFragment
.