页面重构和回流

在了解什么是重构和回流以前,咱们应该先看看浏览器是怎么渲染的?css

浏览器的渲染过程:

1.处理HTML脚本,生成DOM树(DOM树里包含全部的HTML标签,包括display:none和js动态添加的元素等)
2.处理CSS脚本,生成CSSOM树(DOM和CSSOM是独立的数据结构)
3.将DOM树和CSSOM树合并为渲染树,render树中不包含定位和几何信息。虽然,render树与dom树相似但仍是有区别的。render树中不包含隐藏的节点 (好比display:none的节点,还有head节点),由于这些节点不会用于呈现,并且不会影响呈现的,因此就不会包含到 render tree中。注意 visibility:hidden隐藏的元素仍是会包含到 render tree中的,由于visibility:hidden 会影响布局(layout),会占有空间。
4.对render树中的内容进行布局,计算每一个节点的几何外观
5.将渲染树中的每一个节点绘制到屏幕中.jquery

什么是重构和回流

重构:当元素的某些属性发生变化,这些属性又只影响元素的外观和风格,而不改变元素的布局、大小好比颜色、背景。此时触发的浏览器行为称做重构。
回流:当元素的布局、大小规模和显示方式发生改变时,触发的浏览器行为叫回流。并且,每一个页面都会在第一次加载时触发回流。
注意:回流必将引发重绘,而重绘不必定伴随回流。同时,回流对性能的影响要大于重构。浏览器

什么操做会引发重绘、回流

其实任何对render tree中元素的操做都会引发回流或者重绘,好比:缓存

  • 添加、删除元素(回流+重绘)
  • 隐藏元素,display:none(回流+重绘),visibility:hidden(只重绘,不回流)
  • 移动元素,好比改变top,left(jquery的animate方法就是,改变top,left不必定会影响回- 流),或者移动元素到另外1个父元素中。(重绘+回流)
  • 对style的操做(对不一样的属性操做,影响不同。好比,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变——好比文本改变或者图片大小改变而引发的计算值宽度和高度改变;)
  • 还有一种是用户的操做,好比改变浏览器大小,改变浏览器的字体大小等(回流+重绘)

浏览器对回流的优化

由于,回流花销很大,因此大部分浏览器对于回流都会进行优化,浏览器会维护1个队列,把全部会引发回流、重绘的操做放入这个队列,等队列中的操做到了必定的数量或者到了必定的时间间隔,浏览器就会flush队列,进行一个批处理。这样就会让屡次的回流、重绘变成一次回流重绘。数据结构


虽然有了浏览器的优化,但有些代码可能会强制浏览器提早flush队列,这样浏览器的优化可能就起不到做用了。当你请求向浏览器请求一些 style信息的时候,就会让浏览器flush队列,好比:dom

  1. offsetTop, offsetLeft, offsetWidth, offsetHeight
  2. scrollTop/Left/Width/Height
  3. clientTop/Left/Width/Height
  4. width,height
  5. 请求了getComputedStyle(), 或者 IE的 currentStyle

当你请求上面的一些属性的时候,浏览器为了给你最精确的值,须要flush队列,由于队列中可能会有影响到这些值的操做。即便你获取元素的布局和样式信息跟最近发生或改变的布局信息无关,浏览器都会强行刷新渲染队列。布局

如何减小回流、重绘

根据上面触发回流和重绘的操做,咱们能够知道只要减小对render tree的操做(合并屡次多DOM和样式的修改),并减小对一些style信息的请求,就能减小回流、重绘了,尽可能利用好浏览器的优化策略。
具体作法有:
1.直接改变className,若是动态改变样式,则使用cssText(考虑没有优化的浏览器)
2.让要操做的元素进行”离线处理”,处理完后一块儿更新:性能

  • 使用DocumentFragment进行缓存操做,引起一次回流和重绘;
  • 使用display:none技术,只引起两次回流和重绘;
  • 使用cloneNode(true or false) 和 replaceChild 技术,引起一次回流和重绘;

3.不要常常访问会引发浏览器flush队列的属性,若是你确实要访问,利用缓存
4.让元素脱离动画流,减小回流的Render树的规模(即让动画的元素脱离文档流,使用absolute定位等等)。字体

相关文章
相关标签/搜索