写在后面

在探讨明天的配角之前,咱们要先理解一下浏览器的渲染机制。以Google,Firefox,Safari为例,Firefox 应用Geoko——Mozilla 自主研发的渲染引擎,SafariChrome 都应用 webkit

咱们次要以 Webkit的主流程为例

  • 浏览器应用流式布局模型 (Flow Based Layout)
  • 解析HTML 生成 DOM
  • 解析CSS 生成CSSOM 规定树
  • DOM 树与 CSSOM 规定树合并在一起生成渲染树Render Tree
  • 依据渲染树遍历拿到每个节点开始布局,计算每个节点的地位大小信息
  • 将渲染树每个节点绘制到屏幕

回流(Reflow)

下面咱们晓得,咱们会依据 Render Tree 去遍历渲染,所以当咱们的节点产生扭转时,浏览器从新渲染局部节点或者全副文档,咱们称这个过程为回流

大抵整顿会导致回流的一些操作

  • 页面首次渲染
  • 浏览器窗口大小产生扭转
  • 元素尺寸或地位产生扭转
  • 元素内容变动(文字数量或图片大小等等)
  • 元素字体大小变动
  • 增加或者删除可见的DOM元素
  • 激活CSS伪类(例如::hover)
  • 查问某些属性或调用某些办法

次要有上面几个API

盒子操作相干
  • elem.offsetLeft, elem.offsetTop, elem.offsetWidth, elem.offsetHeight, elem.offsetParent
  • elem.clientLeft, elem.clientTop, elem.clientWidth, elem.clientHeight
  • elem.getClientRects(), elem.getBoundingClientRect()
滚动相干
  • elem.scrollBy(), elem.scrollTo()
  • elem.scrollIntoView(), elem.scrollIntoViewIfNeeded()
  • elem.scrollWidth, elem.scrollHeight
  • elem.scrollLeft, elem.scrollTop
其余

上述次要是咱们常常应用的一些API,其余还有一个api曾经有热心网友帮咱们整理出来了

咱们能够看一下
What forces layout / reflow(https://gist.github.com/paulirish/5d52fb081b3570c81e3a)

重绘(Repaint)

当咱们操作的节点上的元素并不导致元素地位发生变化时,比方color,background-color,visibility(留神尽管节点暗藏了,然而元素还在,并且地位也不会发生变化)

浏览器会将新的款式赋值给这些节点,咱们称这个过程为重绘

影响

依照常理也很好了解,因为地位,大小等产生的回流操作相比于仅仅是色彩的变动,带给咱们的视觉直观感触来说,回流是比拟大的。

事实上,回流的确比重绘的老本更大,并且有时候并不是只回流一个元素,甚至会带动父元素或者子元素一起回流。

古代浏览器会对频繁的回流或重绘操作进行优化,浏览器会保护一个队列,当咱们页面产生回流或重绘时,有时候并不是立刻执行,而是先放入保护的队列中,达到肯定工夫后对立去进行绘制

当你拜访以下属性或办法时,浏览器会立即清空队列

clientWidthclientHeightclientTopclientLeft

offsetWidthoffsetHeightoffsetTop、offsetLeft`

scrollWidthscrollHeightscrollTopscrollLeft

widthheight

getComputedStyle()

getBoundingClientRect()

所以当咱们须要应用如上api获取数据时,咱们要重视渲染机会以及取值机会

防止重绘与回流

  • 防止应用 table 布局。
  • 尽可能在 DOM 树的最末端扭转class
  • 防止设置多层内联款式。
  • 将动画成果利用到position属性为absolutefixed的元素上。
  • 防止应用CSS表达式(例如:calc())。
  • 防止频繁操作款式,最好一次性重写style属性,或者将款式列表定义为class并一次性更改class属性。

-防止频繁操作DOM,创立一个documentFragment,在它下面利用所有DOM操作,最初再把它增加到文档中。

  • 也能够先为元素设置display: none,操作完结后再把它显示进去。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
  • 防止频繁读取会引发回流/重绘的属性,如果的确须要屡次应用,就用一个变量缓存起来。
  • 对具备简单动画的元素应用相对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

总结

咱们把页面文档比作一个积木的话,咱们抽离两头或者底部的一个积木块,咱们的积木会从新找到重心并且巩固下来,咱们把这个过程称之为回流

咱们在某个积木上涂上色彩,这并不会造成整个积木的稳固,咱们把这个过程叫做重绘

或者说,咱们简略了解会引起元素地位变动的就会reflow,会引起地位变动的,只是在以前的地位进行扭转背景色彩等,只会repaint

本文首发于什么是回流与重绘 (Reflow & Repaint)(https://www.ahwgs.cn/shenmeshihuiliuyuzhonghui-reflow-repaint.html))