浏览器页面渲染的过程

1,689 阅读3分钟

获取到数据回来渲染的步骤

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节点发生某些改变时就会进行渲染页面的第五步--重排 发生重排的操作:

  1. window大小改变
  2. 元素大小改变 当用js动态修改元素大小的时候会发生重排
  3. 增加或减少dom结构
  4. 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条信息,之后就没有要重排的操作,浏览器就会一次性进行重排。