浏览器渲染
只涉及浏览器客户端渲染
浏览器客户端渲染大体步骤
1.将从服务器获取的HTML文档进行解析、构建成DOM
2.将CSS样式进入载入、解析、构建成CSSDOM
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)——腰花