浏览器渲染
只涉及浏览器客户端渲染
浏览器客户端渲染大体步骤
1.将从服务器获取的HTML文档进行解析、构建成DOM
2.将CSS样式进入载入、解析、构建成CSSDOM
2.5 为每个 DOM Tree 中的元素根据 CSS 的解析结果来确定生成怎样的 renderer
- 当Webkit需要为HTML元素创建RenderObject的时候,首先StyleResolver负责获取样式信息,(其中选择器就在进行,是从右向左解析,来进行匹配的),并返回RenderStyle对象,RenderStyle对象包含了匹配完的结果样式信息
- 每个元素可能需要匹配不同来源的规则,依次是浏览器规则集合、用户规则集合和HTML网页中包含的自定义规则集合.这三个规则的匹配方式是类似的,这里以自定义规则匹配为例;
- 对于自定义规则集合,它先查找ID规则,检测有无匹配的规则,之后依次检测类型规则、标签规则等。如果某个规则匹配上该元素,Webkit把这些规则保存到匹配结果中;
- Webkit对这些规则进行排序。对于该元素需要的样式属性,Webkit选择从高优先级规则中选取,并将样式属性返回。
3.DOM、CSSDOM 合并形成渲染树
4.根据渲染树进行布局,计算元素的几何信息 (回流)
5.进行绘制渲染(重绘)
阻塞渲染
HTML解析器在解析时,会被资源或脚本所阻塞,但并不会影响后续的资源加载(即虽影响了解析渲染,但不影响资源加载)
1.遇到CSS资源时,在CSSDOM构建完成前,浏览器不会渲染任何已处理的内容;并且浏览器会延迟JavaScript的执行和DOM的构建
2.当遇到script标签时,DOM构建将停止,直到脚本执行完
所以 在html页面,css标签资源通常在前,script标签通常在后
(这也是一种常见的优化首屏加载速度的方法)
回流与重绘
1.回流
计算渲染树树在视窗的位置和大小,这一过程即回流。
1.1何时发生回流:
当页面布局或元素的几何信息发生变化时,就会发生回流
具体涉及到:
- 页面首次渲染
- 浏览器窗口大小发生改变
- 元素尺寸或位置发生改变
- 元素内容变化(文字数量或图片大小等等)
- 元素字体大小变化
- 添加或者删除可见的DOM元素
- 激活CSS伪类(例如::hover)
- 查询某些属性或调用某些方法:
一些常用且会导致回流的属性和方法: https://gist.github.com/paulirish/5d52fb081b3570c81e3a
- clientWidth、clientHeight、clientTop、clientLeft
- offsetWidth、offsetHeight、offsetTop、offsetLeft
- scrollWidth、scrollHeight、scrollTop、scrollLeft
- scrollIntoView()、scrollIntoViewIfNeeded()
- getComputedStyle()
- getBoundingClientRect()
- scrollTo()
1.2关于为何查询某些属性或调用某些方法会导致回流
浏览器对于回流的请求,并不是来一次就执行一次,而是对于回流的请求,先放入一个队列中,当达到一定阈值,就好触发回流,即会合并多次回流请求,改为一次执行。
但发生查询某些属性或调用某些方法时,队列会被强制执行并清空,因为需要获取到实时的DOM的位置信息等
2.重绘
将渲染树的元素绘制出来,这一过程即重绘
2.1何时发生重绘
当元素的样式等信息发生变化但不影响几何位置时,会发生重绘
所以,当发生回流时,一定会发生重绘;当发生重绘时,不一定会发生回流
关于提升性能
在了解了相关渲染的原理后,对于提升性能的优化,可能就有了一些思路。
- 减少阻塞渲染
- 减少回流和重绘
对于减少阻塞渲染
可以通过将CSS标签 置前,script标签置后,来实现
减少回流、重绘
- 在批量操作大量DOM时,可以先创建个documentFragment,在其中进行操作
- 在查询、调用某些会引起回流的属性或方法时,可以用变量进行缓存,避免多次重复调用
- css3硬件加速
参考:
1.浏览器的渲染:过程与原理——天方夜
2.前端开发者应知必会:浏览器是如何渲染网页的——余博伦
3.你真的了解回流和重绘吗——腾讯IVWEB团队
4.浏览器的回流与重绘 (Reflow & Repaint)——腰花
5.探究 CSS 解析原理
6.Webkit底层原理(5)--CSS解释器和布局