【整理】浏览器如何呈现页面(三)

通过上两篇的翻译内容(第一篇 , 第二篇),这里作一点小小的深刻和整理html

重温一下这个过程:node

转换

原数据(Bytes)->字符(Characters)

这一步不想多说啥了,如今基本写个网络应用,都有这一步c++

字符(Characters)->标记(tokens)

好比咱们有html文本内如以下:chrome

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <div>
        <h1 class="title">demo</h1>
        <input value="hello">
    </div>
</body>
</html>
复制代码

那变成tokens后,以下:浏览器

tagName: html  |type: DOCTYPE   |attr:              |text: " tagName: |type: Character |attr: |text: \n"
tagName: html  |type: startTag  |attr:              |text: " tagName: |type: Character |attr: |text: \n"
tagName: head  |type: startTag  |attr:              |text: " tagName: |type: Character |attr: |text: \n "
tagName: meta  |type: startTag  |attr:charset=utf-8 |text: " tagName: |type: Character |attr: |text: \n"
tagName: head  |type: EndTag    |attr:              |text: " tagName: |type: Character |attr: |text: \n"
tagName: body  |type: startTag  |attr:              |text: " tagName: |type: Character |attr: |text: \n "
tagName: div   |type: startTag  |attr:              |text: " tagName: |type: Character |attr: |text: \n "
tagName: h1    |type: startTag  |attr:class=title   |text: " tagName: |type: Character |attr: |text: demo"
tagName: h1    |type: EndTag    |attr:              |text: " tagName: |type: Character |attr: |text: \n "
tagName: input |type: startTag  |attr:value=hello   |text: " tagName: |type: Character |attr: |text: \n "
tagName: div   |type: EndTag    |attr:              |text: " tagName: |type: Character |attr: |text: \n"
tagName: body  |type: EndTag    |attr:              |text: " tagName: |type: Character |attr: |text: \n"
tagName: html  |type: EndTag    |attr:              |text: " tagName: |type: Character |attr: |text: \n"
tagName:       |type: EndOfFile |attr:              |text: " 复制代码
  • 好细致,连空格和换行都不放过
  • 能够重点观察一下,token的顺序,以及标签开闭节点之间的关系。
  • 有了一个分类,chrome里分为以下之类:
enum TokenType {
    Uninitialized,
    DOCTYPE,
    StartTag,
    EndTag,
    Comment,
    Character,
    EndOfFile,
  };
复制代码

标记(tokens)->节点(node)

事实上,构建DOM的过程当中,不是等全部Token都转换完成后再去生成节点对象,而是一边生成Token一边消耗Token来生成节点对象,处理token大体以下:bash

void HTMLTreeBuilder::processToken(AtomicHTMLToken* token) {
  if (token->type() == HTMLToken::Character) {
    processCharacter(token);
    return;
  }

  switch (token->type()) {
    case HTMLToken::DOCTYPE:
      processDoctypeToken(token);
      break;
    case HTMLToken::StartTag:
      processStartTag(token);
      break;
    case HTMLToken::EndTag:
      processEndTag(token);
      break;
    //othercode
  }
}
复制代码

节点(node)->DOM

构建DOM主要就是创建起每一个结点的父子兄弟关系,更多细节,看下面连接里的文章。网络

以上大部份内容取自这里dom

这里在加一些内容:post

  • 在构建DOM的过程当中,若是遇到link的标签,当把它插到DOM里面以后,就会触发资源加载,不会影响DOM树的构建,只是说在CSS没处理好以前,构建好的DOM并不会显示出来(渲染时中断)ui

  • 在构建DOM时,HTML解析器若遇到了JavaScript,那么它会暂停构建DOM,将控制权移交给JavaScript引擎,等JavaScript引擎运行完毕,浏览器再从中断的地方恢复DOM构建(Dom构建时中断)

  • 若是有CSS正在处理中,这时候又来了JS,那DOM暂停(要等JS),JS也不会执行(要等CSSOM)。等CSS处理完后,JS再执行,等JS执行完后,DOM再继续。

  • JS的执行要等待位于其前面的CSS和JS加载、执行完。

【未完待续】。。。

相关文章
相关标签/搜索