此篇文章后期有时间会进行更详细的补充。
一、浏览器访问网页时候,做了这几件事:
- DNS 解析
- TCP 三次握手链接
- HTTP 客户端请求和服务端响应
- 客户端渲染
二、客户端渲染有以下几步:
- HTML 代码解析为 DOM ,CSS 代码解析为 CSSOM(CSS Object Model)
- 将 DOM 和 CSSOM 合成一棵渲染树(render tree)
- 根据渲染树布局,计算出渲染树的布局(layout)
- 将渲染树绘制到屏幕
注意:
- 以上几步,不一定按照顺序依次执行的,有时候解析没结束,页面就出现了内容
- render tree 构建前提是必须有 CSSOM 和 DOM,所以先生成 CSSOM 和 DOM
webkit渲染引擎流程
1)、那么问题来了,什么是 DOM 树?
DOM 树全称 Document Object Model(文档对象模型),它是用来呈现以及与任意XML 和 HTML 交互的API,DOM 是载入到浏览器中的文档模型,以节点树的形式来表现文档,每个节点代表文档的构成部分(例如:页面元素、字符串或注释等等)----- 此处还需要补充一下文本节点等各种节点。
2)、那么问题又来了,什么是 CSSOM树?
CSSOM 是一组允许用 Javascript 操纵 CSS 的API。它是继DOM 和 HTML API 之后,又一个操纵 CSS 的接口,从而能够动态地读取和修改 CSS 样式。
1、解析 HTML、CSS,生成 DOM树、CSSOM 树
将 HTML 解析成 DOM树,经历以下几个步骤:
- 编码:将 HTML 原始字节数据转成文件指定编码的字符串
- 令牌化:浏览器会根据 HTML 规范来将字符串转成各种令牌(如 <html>、<body>这样的标签以及标签中的字符串和属性等都会被转成令牌,每个令牌具有特殊含义和一组规则)。令牌记录了标签的开始和结束,通过这个特性可以轻松判断一个标签是否为子标签(假设有<html>和<body>两个标签,当<html>标签的令牌还未遇到它的结束令牌</html>就遇见了<body>标签令牌,那么<body>就是<html>的子标签)。
- 生成对象:将每个令牌转换成定义其属性和规则的对象——节点对象,所有节点对象组成的就是 DOM 树。
CSS 解析成 CSSOM 和 HTML 差不多,CSS 也具有层级关系,比如: div p{color: red} , div 和 p 就具有父子关系,在给 p 标签渲染样式的时候,首先去寻找父标签有 div 的,然后才采取此样式渲染,这也是优化重点,尽量用类名选择器写样式,因为使用标签选择器,浏览器要在大量的标签中进行筛选,速度慢,相同类名少有利于筛选。
整个 DOM 树的构建过程:字节 —— 字符 —— 令牌——节点对象——对象模型。下面通过一个 HTML 代码示例与配图更形象的解析这个过程。
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="main.css"> <title>DOM tree</title> </head> <body> <p> hello ,<span>DOM </span> tree</p> <div><img src="logo.jpg" /></div> </body> </html>
DOM 树构建过程
当遇到 link 标签的时候,停止解析 HTML,获取对应路径下的 css 文件。
body { font-size: 16px } p { font-weight: bold } span { color: red } p span { display: none } img { float: right }
CSSOM 树
注意:
- HTML 在解析生成 DOM 树的时候,可能会因为 CSS 和 JS 加载导致 HTML 停止解析生成 DOM 树,这就是渲染阻塞(优化重点)。
- 为什么是 DOM 树,因为 HTML 标签具有父子关系,树形结构能清晰描述节点之间的关系
- 当 HTML 解析器在遇到 JS 脚本时,会立即停止构建 DOM 树,将控制权移交给 JS 引擎,等到 JS 引擎运行完毕,浏览器才会从中断的地方恢复DOM 树的构建。
- 当 HTML 解析器被脚本阻塞时,解析器虽然会停止构建DOM,但仍会识别该脚本后面的资源,并进行预加载。
2、DOM 和 CSSOM 合成一棵渲染树(render tree)
DOM 和 CSSOM 是独立的对象,并不能直接渲染到页面,需要将 DOM 和 CSSOM 结合在一起,这就是渲染树。
渲染树
- 浏览器从 DOM 的根节点开始遍历每个可见节点并从 CSSOM 找到对应的 CSS 样式规则并应用
- 渲染树是由 DOM 树和 CSSOM 树合并而成,但并不是等 DOM 树 和 CSSOM 树加载完成后才开始合并构建渲染树,三者的构建并无先后顺序,亦非完全独立,而是会存在相互交叉,并行构建。因为会形成一遍加载,一遍解析,一遍渲染的工作现象。
3、根据渲染树布局,计算出渲染树的布局(layout)
- css 布局采用的是盒模型的思维模型来表示节点与节点之间的位置关系,盒模型包括:外边距,内边距,边框,内容。每个节点都是一个小盒子。
- 从渲染树的根节点开始遍历根据屏幕的大小确切到每个节点的位置。
4、将渲染树绘制到屏幕
渲染树布局计算为完成之后,浏览器立即发出 Paint Setup 和 Paint 事件,将渲染树绘制到屏幕上。