一.html页面呈现流程
浏览器把获取到的html代码解析成一个dom树,其中的每个tag都是dom树中的一个节点,根节点就是我们常用的document对象。dom树里包含了所有html标签,包括display:none隐藏东西,还有用js动态添加的元素等等。
浏览器将所有css样式解析成样式结构体,在解析的过程中去掉浏览器不能识别的样式。
dom树和样式结构体组合后构建render tree,能够识别样式的render tree。每个node都有自己的style,但是render
tree不包含隐藏的节点。因为不会呈现。(注:visibility:hidden隐藏的元素还是会包含到render
tree中,因为其样式会影响布局,占有空间。render tree中的每个节点都称为box。)
一旦render tree构建完成,浏览器就根据其开始绘制页面。
二.回流与重绘
1.当render tree中的一部分因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。称为回流(reflow)。每个页面在加载的时候都会出现一次回流,浏览器会使渲染树中受到影响的部分失效,并且重新构造这部分渲染树,完成汇流后,浏览器会重新绘制受到影响的部分到屏幕中,该过程称为重绘。
2.当render tree中的一些元素需要更新属性,而这些属性只会影响元素的外观,而不印象布局,比如背景色等等,称为重绘。
**注:重流一定引起重绘,重绘不一定引起回流。**
何时发生回流:
添加或者删除可见的Dom元素 元素位置发生改变 元素尺寸发生改变 元素内容改变,比如文本改变或者图片大小改变而影响计算值宽度和高度的改变。 页面渲染初始化 浏览器窗口尺寸改变-resize事件发生。
三.优化(减少回流,重排)
1.浏览器本身放入优化策略:
浏览器会维护一个队列,把所有的引起回流,重绘的操作放入这个队列,等队列中的操作到了一定数量或是到了一定时间,浏览器就会flush队列,进行一个批处理。
2.我们要做的就是减少对render tree 的操作,减少一些style信息的请求。
将多次改变样式的操做合并成一次。 将需要多次重排的元素,position属性设为absolute或者fixed,这样次元素就脱离文档流,变化不会影响其他元素。 在内存中多次操作节点,完成后再添加到文档中去。比如,异步获取表格数据,再添加到页面中,我们可以先获取数据,在内存中构建整个表格的html结构,再一次性的添加到文档中去。而不是循环添加。 由于display属性为none的元素不在渲染树中,对隐藏元素的操作不会引发其它元素的重排。如果要对一个元素进行复杂操作,可以先影藏,操作完成后再显示。触发两次重排。 取浏览器重排的属性值,缓存到变量。