#documentdoctypehtmlheadtitle"Cafe"bodyh1"Menu"p"Hot "em"mocha""cocoa"p"Iced latte"1<!DOCTYPE html>2<title>Cafe</title>3<h1>Menu</h1>4<p>Hot <em>mocha</em>5<p>Iced lattetokenizer0x003C0x01210x02440x034F0x04430x0554JShtmlheadtitlebodyh1pem<!DOCTYPE><title>Cafe</title><h1>Menu</h1><p>Hot<em>mocha</em>Iced latteEOFJS
Front: the file, its bytes, the tokenizer and the stack of open elementsBack: the DOM tree, growing one node at a timeChips: tokens travelling to the node they create; slabs: elements pushed and poppedFront left: menu.html, five lines of HTML, and its first six bytes. Middle: the tokenizer and the stack of open elements. Back: the DOM tree. Bytes become characters and characters become tokens. Each token hops from the tokenizer to the node it creates, while element slabs are pushed onto the stack and popped off it. The parser adds the html, head and body elements the file left out, closes the paragraph it left open, and a script finally changes one text node. A real browser parses a page in a few milliseconds and starts building the tree before the last byte arrives. The figure slows it down to one line per step.

Bytes to tokens

  1. A page arrives as bytes: numbers from 0 to 255. The browser decodes them into characters using the page's encoding, usually UTF-8. The first six bytes, 3C 21 44 4F 43 54, become <!DOCT.

Building the tree

The living DOM

What happens

;; step 1/11 · bytes
file     menu.html   (86 bytes)
bytes    3C 21 44 4F 43 54   (hexadecimal)
decode   UTF-8: one byte per character for these
         0x3C → <
         0x21 → !
         0x44 → D
         0x4F → O
         0x43 → C
         0x54 → T

The line breaks between tags also become small text nodes that hold only whitespace. The figure leaves them out, as browser developer tools usually do. A real browser parses a page in a few milliseconds and starts building the tree before the last byte arrives. The figure slows it down to one line per step.