Web 浏览器是一种软件,它从远程服务器(或者本地磁盘)加载文件并将其显示——使用户能够与之交互。浏览器中有一个软件叫浏览器引擎。在不一样的浏览器中,浏览器的某个部分会根据它接收到的文件肯定显示什么,这就是所谓的浏览器引擎。浏览器引擎是每一种主流浏览器的核心软件组件,不一样的浏览器开发商用不一样的名字来称呼他们的引擎。javascript
但标记还不是最终的结果。标记化完成后,接下来,标记将被转换为节点。你能够将节点看做是具备特定属性的不一样对象。实际上,更好的解释是,将节点看做是文档对象树中的独立实体。但节点仍然不是最终结果。 如今,让咱们看一下最后一点。在建立好以后,这些节点将被连接到称为DOM 的树数据结构中。DOM 创建起了父子关系、相邻兄弟关系等。在这个 DOM 对象中,每一个节点之间都创建了关系。如今,这是咱们可使用的东西了。css
这个是咱们很常见的写法html
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="test.css" /> </head> <body> </body> </html> 复制代码
当浏览器接收到原始数据字节并启动 DOM 构建过程时,它还会发出请求来获取连接的 test.css 样式表。当浏览器开始解析 HTML 时,在找到 css 文件的连接标签的同时,它会发出请求来获取它。可能你已经猜到,浏览器仍是接收 CSS 数据的原始字节,从互联网或是本地磁盘。java
当浏览器接收到 CSS 的原始字节时,会启动一个和处理 HTML 原始字节相似的过程。就是说,原始数据字节被转换成字符,而后标记,而后造成节点,最后造成树结构。 什么是树结构?大多数人都知道 DOM 这个词。一样,也有一种 CSS 树结构,,浏览器不能使用 HTML 或 CSS 的原始字节。必须将其转换成它能识别的形式,也就是这些树形结构。浏览器
渲染树包含页面上全部关于可见 DOM 内容的信息以及不一样节点所需的全部 CSSOM 信息。注意,若是一个元素被 CSS 隐藏,例如使用 display; none,那么节点就不会包含在渲染树中。隐藏元素会出如今 DOM 中,但不会出如今渲染树中。这是由于渲染树结合了来自 DOM 和 CSSOM 的信息,因此它知道不能把隐藏元素包含在树中。服务器
咱们已经获得了在屏幕上显示元素所需的全部信息。咱们只要把它展现给用户。这就是这个阶段的所有工做。有了元素内容(DOM)、样式(CSSOM)和计算得出的元素的精确布局信息,浏览器如今就能够将节点逐个“绘制”到屏幕上了。元素能够呈如今屏幕上了!markdown
通俗的解释为有东西阻止了屏幕上节点的实际绘制,在成功绘制以前,必须构造 DOM 和 CSSOM,所以,HTML 和 CSS 都是渲染阻塞资源。网络
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>testRander</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<p>浏览器页面渲染机制</p>
<img src="http://spage.haimati.cn/activityImage/newplan.jpg">
</body>
</html>
复制代码
这是一个很是常见的文档。样式表 style.css简单定义样式:数据结构
* { font-size: 20px; } body { background-color: antiquewhite; } 复制代码
一段简单的文本和图像呈如今屏幕上。async
根据前面的解释,浏览器从磁盘(或网络)读取 HTML 文件的原始字节并将其转换为字符。字符被进一步解析为标记。当解析器遇到< link rel="stylesheet" href="style.css">时,就会请求获取 CSS 文件 style.css。DOM 构造继续进行,当 CSS 文件返回一些内容后,CSSOM 构造就开始了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>testRander</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<p id="title">浏览器页面渲染机制</p>
<img src="http://spage.haimati.cn/activityImage/newplan.jpg">
<script>
let title = document.getElementById("title");
console.log("title is: ", title);
</script>
</body>
</html>
复制代码
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>testRander</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script>
let title = document.getElementById("title");
console.log("title is: ", title);
</script>
<p id="title">浏览器页面渲染机制</p>
<img src="http://spage.haimati.cn/activityImage/newplan.jpg">
</body>
</html>
复制代码
当脚本试图访问一个 id 为 header 的 DOM 节点时,因为 DOM 尚未完成对文档的解析,因此它还不存在。这把咱们带到了另外一个重要的问题。脚本的位置很重要。
在默认状况下,每一个脚本都是一个解析器阻断器!DOM 的构建老是会被打断。不过,有一种方法能够改变这种默认行为。若是将 async 关键字添加到脚本标签中,那么 DOM 构造就不会中止。DOM 构造将继续,脚本将在下载完成并准备就绪后执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>testRander</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="test.js" async></script>
<p id="title">浏览器页面渲染机制</p>
<img src="http://spage.haimati.cn/activityImage/newplan.jpg">
</body>
</html>
复制代码
把js放入test.js中进行引入
let title = document.getElementById("title"); console.log("title is: ", title); 复制代码
这样DOM的构建就不会中止,脚本在构造完成后执行。