获取到数据回来渲染的步骤
1. html代码解析成dom树
数据请求回来,网络进程在接收到响应头后,根据响应头的 content-type 字段判断文件类型,若是 text/html,浏览器会判断这是一个 html 类型的文件,然后就会将html文件解析成DOM树,html的一个个标签组成DOM树的节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<li>hello</li>
</ul>
</body>
</html>
vndoe = {
tag: 'ul',
children: [{
tag: 'li',
children: [
{ vnode: { text: 'hello' } }
]
}]
}
可以把这些节点看成一个个节点对象,整个页面的节点对象就构成了DOM树
2. css代码解析成cssom树
接着就是将css解析成cssom树,cssom树根dom树一样也是由一个个样式节点构成,与dom树的各个节点不是一一对应的,是相互独立的两个数据结构
3. 结合dom树和cssom树生成render树
接着dom树和cssom树会结合成render树也叫渲染树,一个个dom的节点对象都有其计算好的样式规则
4. 布局,将渲染树所有dom节点进行平面合成
当生成渲染树以后,浏览器就会根据渲染树结构来进行布局(也可以叫做回流或重排),浏览器要做的事情是要弄清楚各个节点在页面中的确切位置和大小
5. 绘制到屏幕上
最后就是绘制到浏览器上面
渲染
网页生成的时候至少渲染一次,也就是绘制到屏幕上
重排(回流)
当页面dom节点发生某些改变时就会进行渲染页面的第五步--重排 发生重排的操作:
- window大小改变
- 元素大小改变 当用js动态修改元素大小的时候会发生重排
- 增加或减少dom结构
- js代码中出现以下单词开头的属性时会发生重排 offset... | client... | scroTop...|
简单来说就是所有导致元素发生几何变化的操作
重绘
与重绘相反,所有导致元素发生非几何变化的操作能引起浏览器的渲染操作,比如颜色变化 并且重排一定重绘重绘不一定重排
来道题目
下面js代码会让浏览器发生几次重排几次重绘呢????
<script>
let el =document.getElementById('app')
el.style.width=(el.offsetWidth+1)+'px'
el.style.width=1+px
</script>
相信很多人会觉得发生3次重排3次重绘因为el的宽度改变2次,出现offset开头的属性一次一共3次 接下来介绍一下浏览器的优化机制相信你心中的答案会有所改变
浏览器优化
当改变元素集合信息导致发生重拍时,浏览器提供一个渲染队列用于临时改变的重排,浏览器继续执行代码,如果还有几何信息发生改变,继续入队,直到没有元素几何改变的信息,然后浏览器会根据渲染队列一次性来批量优化重排过程 如果出现offset开头的属性会强制刷新渲染队列,包括offset开头的属性,但是如果出现offset开头的属性时队列没有信息,offset开头的属性就会自己入列不会强制刷新渲染队列
<script>
let el =document.getElementById('app')
el.style.width=(el.offsetWidth+1)+'px'
el.style.width=1+px
</script>
所以js代码会让浏览器发生重排一次重绘一次 首先出现offset开头的属性,但是这个时候渲染队列是空的,所以浏览器暂且不会发生重排,之后elw的宽度改变2次入队,渲染队列就有3条信息,之后就没有要重排的操作,浏览器就会一次性进行重排。