【整理】瀏覽器如何呈現頁面(三)

通過上兩篇的翻譯內容(第一篇 , 第二篇),這裏作一點小小的深刻和整理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加載、執行完。

【未完待續】。。。

相關文章
相關標籤/搜索