02 HTML 网页和结构

1 网页构成

1.1 基本元素和树状结构

基本元素

基本元素 说明
HTML 文本 用 HTML 语言撰写的文档。
CSS 一种样式表语言,用来描述元素的显示信息。
JavaScript 一种解释型的脚本语言,主要目的是控制用户端逻辑、同用户交互等,它可以修改 HTML 元素及其内容。
各种资源文件 每种资源文件都是由 URL(URI 的一种实现) 标记的。

例子: 一个简单完整的 HTML 网页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- HTML  文本 -->
<html>
<head>
<!-- CSS 代码 -->
<style type="text/css">
img {
width: 100px;
}
</style>

</head>
<body>
<!-- 图片资源 -->
<img src="apic.png" alt=""/>
<div>Hello World!</div>
<!-- JavaScript 代码 -->
<script type="text/javascript">
window.onload = function () {
console.log('window.onload()')
}
console.log('It\'s me')
</script>

</body>
</html>

树状结构

1.2 HTML5 新特性

HTML5新特性中对网页结构影响较大的功能 说明
HTML5 视频 引入了一个新的 video 元素,支持在网页中播放视频。
Canvas2D 通过定义一个新的 canvas 元素,网页开发者利用该元素的 2D 绘图上下文调用标准定义的接口,绘制常见的 2D 图形,例如点、线、矩形、多边形等。
WebGL 使用 canvas 元素,网页开发者可以利用该元素的 3D 绘图上下文调用标准定义的接口,绘制 3D 图形,这些接口类似于 OpenGL ES 的接口。
CSS 3D 变换(transform)和转换(transition) 可以作用于 HTML 的任意可视元素,制造出各种绚丽的 3D 效果。

示例, 使用 HTML5 新功能视频、2D 和 3D Canvas 的网页代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<html>
<head>
<style type="text/css">
video, div, canvas {
/* CSS 3D 变换 */
-webkit-transform: rotateY(30deg) rotateX(-45deg);
}
</style>

</head>
<body>
<!-- HTML5 video -->
<video src="https://vd1.bdstatic.com/mda-hefhw52tjvn7dfmx/mda-hefhw52tjvn7dfmx.mp4?playlist=%5B%22hd%22%2C%22sc%22%5D&auth_key=1494257527-0-0-3388dfaedf2e8c469332e6663b90fa82&bcevod_channel=nwise_search"></video>
<div>
<canvas id="a2d"></canvas><br>
<canvas id="a3d"></canvas>
</div>
<script type="text/JavaScript">
var size = 300

// canvas 2D 绘图
var a2dCtx = document.getElementById('a2d').getContext('2d')
a2dCtx.canvas.width = size
a2dCtx.canvas.height = size
a2dCtx.fillStyle = 'rgba(0, 192, 192, 80)'
a2dCtx.fillRect(0, 0, 200, 200)

// canvas 3d, e.g. webGL 绘图
var a3dCtx = document.getElementById('a3d').getContext('experimental-webgl')
a3dCtx.canvas.width = size
a3dCtx.canvas.height = size
a3dCtx.clearColor(0.0, 192.0/255.0, 192.0/255.0, 80.0/255.0)
a3dCtx.clear(a3dCtx.COLOR_BUFFER_BIT)
</script>

</body>
</html>

2 网页结构

2.1 框结构

说明: 每个框结构都包含一个 HTML 文档,而框里面的文档还可以再嵌入框。
注意: 多框结构的网页非常不适合移动领域,因为该结构对触控操作来说的确是一场灾难,但是它依然存在。
相关标签

  • frameset
  • frame
  • iframe

多框结构的网页

2.2 层次结构

网页的层次结构


1
2
3
4
5
body # 根层,对应着网页文档对象
video # 为 video 创建一个新层可以更有效地处理视频解码器和浏览器之间的交互和渲染问题
div # 需要进行 3D 变换(被 CSS 属性-webkit-transform 修饰了)
canvas # H5 2D 和 3D 绘图操作
canvas # H5 2D 和 3D 绘图操作

在哪种情况下会产生新的层?
对于不同的渲染引擎,它们的策略可能是不一样的,但有一些基本原则,建第 7 章。

2.3 实践: 理解网页结构

2.3.1 实践1: 框结构

源码

1
2
3
4
5
├── 2-1_html.html
├── 2-2-1_frameset.html
├── 2-2-1_main.html # 入口
├── 2-2_layer.html
└──2017-05-07-23-03-12.jpg

2.3.2 实践2: 层次结构

源码

观察网页的层次结构

  1. 用浏览器打开 2-2_layer.html网页,然后打开 Chrome 浏览器的开发者工具。
  2. 打开 Rendering 面板

  3. 勾选 Layer Borders

3 Webkit 的网页渲染过程

3.1 加载和渲染

网页的渲染过程
浏览器的主要作用就是将用户输入的 URL 转变为可视化的图像。技术上来说包含两个过程

  1. 网页加载过程: 从 URL 到构建 DOM 树;
  2. 网页渲染过程: 从 DOM 树到生成可视化图像。

本书统称这两个过程为网页的渲染过程。

3.2 Webkit 的渲染过程

3.2.1 相关数据和模块

数据

  • 网页内容
  • DOM
  • 内部表示和图像

模块

  • HTML 解释器
  • CSS 解释器
  • JavaScript 引擎
  • 布局和绘图模块

3.2.2 渲染过程

根据数据的流向,这里将渲染过程分为3个阶段

  1. 从网页的 URL 到构建完 DOM 树;
  2. 从 DOM 树到构建完 WebKit 的绘图上下文;
  3. 从绘图上下文到生成最终的图像。

(1) 从网页 URL 到 DOM 树

数组表示的是基本顺序,当然也不是严格一致,这个过程可能重复并且可能交叉

  1. 当用户输入网页 URL 的时候,WebKit 调用其资源加载器加载该 URL 对应的网页。
  2. 加载起依赖网络模块的建立连接,发送请求并接收答复。
  3. WebKit 接收到各种网页或者资源的数据,其中某些资源可能是同步或异步获取的。
  4. 网页被交给 HTML 解释器转变成一系列的词语(Token)。
  5. 解释器根据词语构建节点(Node),形成 DOM 树。
  6. 如果节点是 JavaScript 代码的话,调用 JavaScript 引擎解释并执行。
  7. JavaScript 代码可能会修改 DOM 树的结构。
  8. 如果节点需要依赖其它资源,例如图片、CSS、视频等,调用资源加载器来加载它们,但是它们是异步的,不会阻碍当前 DOM 树的继续创建;如果是 JavaScript 资源 URL(没有标记异步方式),则需要停止当前 DOM 树的创建,直到 JavaScript 的资源加载并被 JavaScript 引擎执行后才继续 DOM 树的资源。

(2) WebKit 利用 CSS 和 DOM 树构建 RenderObject 树直到绘图上下文

  1. CSS 文件被 CSS 解释器解释成内部表示结构。
  2. CSS 解释器工作完成之后,在 DOM 树上附加解释后的样式信息,这就是 RenderObject 树
  3. RenderObject 节点在创建的同时,WebKit 会根据网页的层次结构创建 RenderLayer 树,同时构建一个虚拟的绘图上下文。其实这中间还有复杂的内部过程,先不展开。

(3) 根据绘图上下文来生成最终的图像,这一过程主要依赖 2D 和 3D 图形库。

  1. 绘图上下文是一个与平台无关的抽象类,它将每个绘图操作桥街道不同的具体实现类,也就是绘图具体实现类。
  2. 绘图实现类可能有简单的实现,可能有复杂的实现。在 Chromium 中,它的实现相当复杂,需要 Chromium 的合成器来完成复杂的多进程和 GPU 加速机制,这在后面会涉及。
  3. 绘图实现类将 2D 图形库或者 3D 图形库绘制的结果保存下来,交给浏览器来连同浏览器界面一起显示。

3.3 实践: 从网页到可视化结果

示例代码 2-1_html
Google DevTools performance
注意: 为了排除 chrome 扩展的影响,需要在隐私模式下查看。
性能分析

  1. 通过阶段化分析,网页开发这理解 onload 事件和 DOMContentLoaded 事件什么时候被触发,从而可以在 JavaScript 代码中注册相应的回调函数。
  2. 在 DOM 的构建过程中需要执行 JavaScript 代码,所以需要特别注意这部分代码对网页 DOM 的访问问题,因为这个时候 DOM 可能还未创建完成,因而 JavaScript 代码不能访问 DOM 结构。

第一阶段

  • 从网页 URL 到 DOM 树

第二阶段到第三阶段

  • WebKit 利用 CSS 和 DOM 树构建 RenderObject 树直到绘图上下文。
  • 根据绘图上下文来生成最终的图像,这一过程主要依赖 2D 和 3D 图形库