浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分,一是渲染引擎,另一个是JS引擎,渲染引擎在不同的浏览器中也不是都相同的.目前市面上常见的浏览器内核可以分为4种: Trident( IE ), Gecko( FireFox ), Blink( Chrome,Opera ), Webkit( Safari ),以 Webkit 为例,对现代浏览器的渲染过程进行一个深度的剖析
简介要点如下:
大体上分为如下三部分
浏览器会解析三个东西:
1.1 一是HTML/SVG/XHTML, HTML 字符串描述了一个页面的结构,浏览器会把 HTML 结构字符串解析转换 DOM 树形结构
1.2 二是CSS,解析 CSS 会产生 CSS 规则树,它和 DOM 结构比较像
1.3 三是 JavaScript 脚本,等到 JavaScript 脚本文件加载后, 通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree
解析完成后,浏览器引擎会通过 DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree
2.1 Rendering Tree 渲染树并不等同于 DOM树,渲染树只会包括需要显示的节点和这些节点的样式信息
2.2 CSS 的Rule Tree 主要是为了完成匹配并把 CSS Rule 附加上 Rrendering Tree 上的每个 Element(也就是每个 Frame)
2.3 然后,计算每个 Frame 的位置,又叫做 layout 和 reflow 过程
最后通过调用操作系统 Native GUI 的 API 绘制
假设有段 HTML 文本:
<html>
<head>
<title>Web page parsingtitle>
head>
<body>
<div>
<h1>Web page parsingh1>
<p>This is an example Web page.p>
div>
body>
html>
DOM 会捕获页面的内容,但浏览器还需要知道页面如何展示, 所以需要构建CSSOM
构建CSSOM的过程和构建DOM的过程非常相似,当浏览器接收到一段CSS,浏览器首先要做的是识别出Token,然后构建节点并生成CSSOM
假设有这一段CSS:
body {font-size: 16px;}
p {color: red;}
p span {display:none;}
span {font-size: 14px;}
img {float: right;}
在经过一系列步骤后生成的CSSOM:
从图中还可以看出.body节点的子节点继承了 body 的样式规则(font-size: 16px).这就是层叠规则以及CSS为什么叫CSS(层叠样式表)
注意:CSS 匹配 HTML 元素是一个相当复杂和有性能问题的事情,所以,DOM树要小,CSS要尽量用id和class,不要过度层叠下去
生成 DOM 树和 CSSOM 树之后,就要将这两棵树组合为渲染树.
渲染树只会包括需要显示的节点和这些节点的样式信息,如果某个节点是 display: none ,n那么就不会再渲染树中显示
渲染过程中,如果遇到 就停止渲染,执行 JS 代码.因为浏览器有 GUI 渲染线程与 JS 引擎线程,为了防止渲染出现不可预期的结果,这两个线程是互斥的关系. JavaScript 的加载,解析与执行会阻塞 DOM 的构建,也就是说,在构建 DOM 的时候,HTML 解析器若遇到了 JavaScript,就会暂停构建 DOM,等到 JavaScript 加载完毕,浏览器再从中断的地方恢复 DOM 构建
JS 文件不只是阻塞 DOM 的构建,它会导致 CSSOM 也阻塞 DOM 的构建
因为JavaScript不只是可以改 DOM,它还可以改 CSSOM.因为不完整的 CSSOM 是无法使用的,所以如果浏览器此时尚未完成 CSSOM 的下载和构建,却想要加载运行脚本,那么浏览器将延迟脚本执行和 DOM 构建,直至其完成 CSSOM 的下载和构建.也就是说, 在这种情况下,浏览器会先下载并构建 CSSOM,再执行JavaScript,最后再继续构建 DOM
因此,想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的原因.当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性