浏览器的回流与重绘
了解浏览器的回流(Reflow)与重绘(Repaint)
# 基础准备
首先我们要知道浏览器渲染页面的大致流程,即浏览器是怎么处理HTML和CSS文件的.
- 图片来自@Berwin
从上图很明显的能看出来,浏览器先读取HTML文件并构建DOM,然后读取CSS文件构建CSSDOM,接着把DOM和CSSDOM结合形成Render Tree.浏览器根据Render Tree知道了各个节点的样式,找到各个节点处于页面的哪个位置(Layout),最后浏览器就在屏幕上绘制像素(Paint).
# 回流
当Render Tree中部分或全部元素的尺寸、结构或某些属性发生变化时,浏览器重新构建文档的过程成为回流. 导致回流的操作:
- 页面首次渲染
- 浏览器窗口大小发生改变
- 元素尺寸或位置发生改变
- 元素内容变化(文字数量或图片大小等等)
- 元素字体大小变化
- 添加或者删除可见的DOM元素
- 激活CSS伪类(例如::hover)
- 查询某些属性或调用某些方法
一些常用且会导致回流的属性和方法:
clientWidth、clientHeight、clientTop、clientLeftoffsetWidth、offsetHeight、offsetTop、offsetLeftscrollWidth、scrollHeight、scrollTop、scrollLeftscrollIntoView()、scrollIntoViewIfNeeded()getComputedStyle()getBoundingClientRect()scrollTo()
# 重绘
当Render Tree中元素的样式改变但不影响其在Render Tree中的位置时,浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘.
如改变元素的color.
# 对比
回流必将引起重绘,重绘不一定会引起回流。 所以回流比重绘的代价要更高.有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。