赞
踩
在《Effective前端6:避免页面卡顿》这篇里面介绍了浏览器渲染页面的过程:
并且《从Chrome源码看浏览器如何构建DOM树》介绍了第一步如何解析Html构建DOM树,这个过程大概如下:
浏览器每收到一段html的文本之后,就会把它序列化成一个个的tokens,依次遍历这些token,实例化成对应的html结点并插入到DOM树里面。
我将在这一篇介绍第二步Style的过程,即CSS的处理。
在构建DOM的过程中,如果遇到link的标签,当把它插到DOM里面之后,就会触发资源加载——根据href指明的链接:
<link rel="stylesheet" href="demo.css">
上面的rel指明了它是一个样式文件。这个加载是异步,不会影响DOM树的构建,只是说在CSS没处理好之前,构建好的DOM并不会显示出来。用以下的html和css做试验:
- <!DOCType html>
- <html>
- <head>
- <link rel="stylesheet" href="demo.css">
- </head>
- <body>
- <div class="text">
- <p>hello, world</p>
- </div>
- </body>
demo.css如下:
- .text{
-
- font-size: 20px;
- }
- .text p{
-
- color: #505050;
- }
从打印的log可以看出(添加打印的源码略):
[DocumentLoader.cpp(558)] “<!DOCType html>n<html>n<head>n<link rel=”stylesheet” href=”demo.css”> n</head>n<body>n<div class=”text”>n <p>hello, world</p>n</div>n</body>n</html>n”
[HTMLDocumentParser.cpp(765)] “tagName: html |type: DOCTYPE|attr: |text: “
[HTMLDocumentParser.cpp(765)] “tagName: |type: Character |attr: |text: n”
[HTMLDocumentParser.cpp(765)] “tagName: html |type: startTag |attr: |text: “
…
[HTMLDocumentParser.cpp(765)] “tagName: html |type: EndTag |attr: |text: “
[HTMLDocumentParser.cpp(765)] “tagName: |type: EndOfFile|attr: |text: “
[Document.cpp(1231)] readystatechange to Interactive
[CSSParserImpl.cpp(217)] recieved and parsing stylesheet: “.text{n font-size: 20px;n}n.text p{n color: #505050;n}n”
在CSS没有加载好之前,DOM树已经构建好了。为什么DOM构建好了不把html放出来,因为没有样式的html直接放出来,给人看到的页面将会是乱的。所以CSS不能太大,页面一打开将会停留较长时间的白屏,所以把图片/字体等转成base64放到CSS里面是一种不太推荐的做法。
CSS解析和html解析有比较像的地方,都是先格式化成tokens。CSS token定义了很多种类型,如下的CSS会被拆成这么多个token:
经常看到有人建议CSS的色值使用16位的数字会优于使用rgb的表示,这个是子虚乌有,还是有根据的呢?
如下所示:
如果改成rgb,它将变成一个函数类型的token,这个函数需要再计算一下。从这里看的话,使用16位色值确实比使用rgb好。
这里不关心它是怎么把tokens转化成style的规则的,我们只要看格式化后的styleRule是怎么样的就可以。每个styleRule主要包含两个部分,一个是选择器selectors,第二个是属性集properties。用以下CSS:
- .text .hello{
-
- color: rgb(200, 200, 200);
- width: calc(100% - 20px);
- }
-
- #world{
-
- margin: 20px;
- }
打印出来的选择器结果为(相关打印代码省略):
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。