页面渲染1——创建对象模型
Before the browser can render the page it needs to construct the DOM and CSSOM trees. As a result, we need to ensure that we deliver both the HTML and CSS to the browser as quickly as possible.
在页面进行渲染之前,页面会创建DOM和CSSOM树,所以我们要确保尽快的给浏览器传送HTML和CSS。
- Bytes → characters → tokens → nodes → object model.
- HTML 标签被发送到一个文档对象模型( Document Object Model (DOM)), CSS标签被传送给一个CSS对象模型 CSS Object Model (CSSOM).
- DOM和CSSOM是相互独立的数据结构
- 谷歌浏览器中开发者工具允许我们捕捉和检查DOM和CSSOM创建和执行时候的消耗
Document Object Model (DOM)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1"> <link href="style.css" rel="stylesheet"> <title>Critical Path</title> </head> <body> <p>Hello <span>web performance</span> students!</p> <div><img src="awesome-photo.jpg"></div> </body> </html>
浏览器在处理上面的简单页面要做什么?
- 转换: 浏览器从内存亦或网络中读取了HTML的原生字节,并将它们转化成基于特定编码(例如:UTF-8)的字节。
- 词法语义化: 浏览器将字节字符串转换成独一无二的token,按照W3C HTML5标准转换的,例如转换成“<html>”"<body>"和其他包含尖叫括号的字符串。每一个token有一个特殊的意义以及一套规则。
- 词法分析: token将被转换成"对象"来表明它们的属性和规则
- 构造DOM: 最终,因为HTML标记定义了不同标签之间的关系(一些标签包含另一些标签),被创建的对象连接成树形数据结构,并且在原始的标记中捕捉了parent-child的关系。
最后输出的是文本对象模型(DOM),浏览器使用它进行更加深入的操作。
所有的过程可以简化成:将bytes转换成characters,定义tokens,将tokens转化成nodes,建立DOM树。整个过程将会耗费一些时间,特别是处理大量HTML时。
上图展示了浏览器将html解析成DOM树所需要的时间是5毫秒,如果html多的话会耗时更长。
DOM树只是展示了网页标记的属性和关系,但是没有告诉我们任何关于元素该如何渲染的事情,这些都是CSSOM会做的事情。
CSS Object Model (CSSOM)
DOM树形成之后,进行了外部css文件的请求,返回的内容如下:
body { font-size: 16px } p { font-weight: bold } span { color: red } p span { display: none } img { float: right }
我们需要获取的css变成浏览器可以操作额对象,所以和HTML标记操作过程类似,css操作过程如下:
css字节被转化成字符,然后tokens再被转化成nodes,最后连接成树,叫做“CSS对象模型”,亦或简称为CSSOM:
为什么要有个树形结构呢?因为可以实现样式的递归和继承。例如body上的font-size样式可以被body下面的所有元素继承。
每一个浏览器都会给节点设置相应的“用户代理样式user agent style”,我们自己书写的样式将会重写浏览器自定义的默认样式。
谷歌浏览器开发工具中展示了CSSOM形成以及样式覆盖的总时间,和HTML解析显示的字段不一样,它不是Parse CSS而是Recalculate Style;
上面展示了上例中的样式在浏览器中执行需要约0.6毫秒,并且影响了8个元素。记住,CSSOM树和DOM树是完全独立的数据结构,浏览器隐藏了一个重要的步骤。下一节,让我们说一说连接DOM树和CSSOM树的渲染树(render tree )