Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
154 views
in Technique[技术] by (71.8m points)

javascript - When does parsing HTML DOM tree happen?

I always see a rendering flow for a web page like the following image shows: enter image description here

So the painting only begins after DOM tree is parsed and CSSOM is created, right? Another saying is, putting <script> in the end of <body> is the best practice so that the page renders something before script is downloaded.

My question is, when does parsing DOM tree happens and how can we say it is done? In my understanding, <script> in the end is also part of DOM tree, and only if the script loaded can we call the DOM tree is created. The browser reads the html file from top to bottom, creating the DOM Tree and when it sees a <script>, it stops to download and execute it until the parse goes through the whole page. Or, does the page paints the page at the same time of parsing DOM tree?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

TL;DR: Parsing starts instantaneously after receiving the document.

Parsing and painting

For a more detailed explanation, we need to dive into the way rendering engines work.

Rendering engines parse the HTML document and create two trees: the content tree and the render tree. A content tree contains all DOM nodes. The render tree contains all styling information (the CSSOM) and only the DOM nodes that are required to render te page.

As soon as the render tree has been created, the browsers goes through two processes: applying layout and painting each DOM node. Applying layout means calculating the exact coordinates where a DOM node should appear on the screen. Painting means actually rendering the pixels and applying stylistic properties.

This is a gradual process: browsers won't wait until all HTML is parsed. Parts of the content will be parsed and displayed, while the process continues with the rest of the contents that keeps coming from the network.

You can see this process happening in your browser. For example, open the Chrome Developer Tools and load a site of your choice.

Network tab

After recording activity in the Network tab, you'll notice that parsing starts while downloading the document. It recognises resources and starts downloading them. The blue vertical line indicates the DOMContentLoaded event and the red vertical line indicates the load event.

Timeline tab

Recording a timeline gives you much more insight in what happens under the hood. I have included the screenshot above as an example to indicate that painting happens while parsing the document. Note that the initial paint occurs just before it continues parsing another part of the document. This process continues until it reaches the end of the document.

Single threaded

The rendering engine is single threaded. Almost everything, except network operations, happens in this thread.

Combine that with the synchronous nature of the web. Developers expect <script>'s to be parsed and executed immediately (that is: as soon as the parser reaches a script tag). That means that:

  1. The resource must be fetched from the network (this might be a slow process due to DNS lookups and speed of connection).
  2. The content of the resource is passed to the Javascript interpreter.
  3. The interpreter parses and executes the code.

Parsing the document halts until this process finishes. You don't improve the total parsing time by including <script>'s at the end of the document. It does enhance the user experience, as the process of parsing and painting isn't interrupted by <script>'s that need to be executed.

It is possible to work around this issue by marking the resource with defer and / or async. async downloads the file during HTML parsing and will pause the HTML parser to execute it when it has finished downloading. defer downloads the file during HTML parsing and will only execute it after the parser has completed.

Speculative parsing

Some browsers aim to work around the blocking aspect of <script>'s by using so called speculative parsing. The engine parses ahead (and runs the HTML tree construction!) while scripts are being downloaded and executed. Firefox and Chrome use this technique.

You can imagine the performance gain if a speculation succeeds (eg. the DOM wasn't altered by the scripts that are included in the document). Waiting for the scripts to execute wasn't necessary and the page has been painted successfully. The downside is that there's more work lost when the speculation fails.

Luckily for us, very smart people work at these technologies, so even using document.write properly won't break this process. Another rule of thumb is not to use document.write. For example, it could break the speculative tree:

// Results in an unbalanced tree
<script>document.write("<div>");</script>

// Results in an unfinished token
<script>document.write("<div></div");</script>

Further reading

The following resources are worth your time reading:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...