The major web browsers load web pages in basically the same way. This process is known as parsing and is described by the HTML5 specification. A high-level understanding of this process is critical to writing web pages that load efficiently.

Parsing overview

As chunks of the HTML source become available from the network (or cache, filesystem, etc), they are streamed to the HTML parser. Next, in a process known as tokenization, the parser iterates through the source generating a token for (most notably) each start tag, end tag and character outside of a tag.

For example the input source <b>hello</b> yields 7 tokens:

start-tag { name: b }
character { data: h }
character { data: e }
character { data: l }
character { data: l }
character { data: o }
end-tag { name: b }

After each token is generated it is serially passed to the next major subsystem: the tree builder. The tree builder dynamically modifies the Document's DOM tree to reflect the new token.

The 7 input tokens above yield the following DOM tree:

<html>
<head>
<body>
<b>
"hello"

Fetching subresources

A frequent operation performed by the tree builder is creating a new HTML element and inserting it into the Document. It is at the point of insertion that HTML elements which load subresources begin fetching the subresource.

Running scripts

This parsing algorithm seems to translate HTML source into a DOM tree as efficiently as possible. That is, except for one wrinkle: scripts. When the tree builder encounters an end-tag token for a script, it must serially execute the script before parsing can continue (unless the associated script start-tag has the defer or async attribute).

There are two significant preconditions which must be fulfilled before a script can execute:

  1. If the script is external its source must be fully downloaded.
  2. For any script, all stylesheets in the document must be fully downloaded.

This means often the parser must idly wait while scripts and stylesheets are downloaded.

Why must parsing halt?

Well, a script may document.write something which affects further parsing or it may query something about the DOM which would yield incorrect results if parsing had continued (for instance the number of image elements in the DOM).

Why wait for stylesheets?

A script may expect to access the CSSOM directly or it may query an attribute of a DOM node which depends on the stylesheet (for example, how wide is a certain <table>).

Is it inefficient to block parsing?

Yes. Subresource download times often have a large constant factor limited by round trip time. This means it is faster to download two resources in parallel than to download the same two in serial. More obviously, the browser is also free to do CPU work while waiting on the network. For these reasons it is critical to efficient loading of a web page that subresource fetches are initiated as soon as possible. When parsing is blocked, the tree builder is not able to insert subsequent elements into the DOM, and thus subsequent subresource downloads are not initiated even if the HTML source which includes them is already available to the parser.

Mitigating blocking

As I've blogged previously, when the parser becomes blocked WebKit will run a lightweight parser known as the preload scanner. It mitigates the blocking problem by scanning ahead and fetching certain subresource that may be required. Other browsers employ similar techniques.

It is important to note that even with preload scanning, parsing is still blocked. Nodes cannot be added to the DOM tree. Although I haven't covered how a DOM tree becomes a render tree, layout or painting, it should be obvious that before a node is in the DOM tree it cannot be painted to the screen.

Finishing parsing

After the entire source has been parsed, first all deferred scripts will be executed (waiting for their source and all pending stylesheets to download). Their completion triggers the DOMContentLoaded event to be fired. Next, the parser will wait for any pending async scripts to finish loading and executing. Finally, once all subresources have finished downloading, the window's load event will be fired and parsing is complete.

Takeaway

With this understanding, it becomes clear how important it is to carefully consider where and how stylesheets and scripts are included in the document. Those decisions can have a significant impact on the efficiency of the page load.

How a web page loads的更多相关文章

  1. [转]How WebKit Loads a Web Page

    ref:https://www.webkit.org/blog/1188/how-webkit-loads-a-web-page/ Before WebKit can render a web pag ...

  2. 解读Web Page Diagnostics网页细分图

    解读Web Page Diagnostics网页细分图 http://blog.sina.com.cn/s/blog_62b8fc330100red5.html Web Page Diagnostic ...

  3. 网页细分图结果分析(Web Page Diagnostics)

    Discuz开源论坛网页细分图结果分析(Web Page Diagnostics) 续LR实战之Discuz开源论坛项目,之前一直是创建虚拟用户脚本(Virtual User Generator)和场 ...

  4. Atitit.web三大编程模型 Web Page Web Forms 和 MVC

    Atitit.web三大编程模型 Web Page    Web Forms 和 MVC 1. 编程模型是 Web Forms 和 MVC (Model, View, Controller). 2.  ...

  5. [转]Calling Web Service Functions Asynchronously from a Web Page 异步调用WebServices

    本文转自:http://www.codeproject.com/Articles/70441/Calling-Web-Service-Functions-Asynchronously-from Ove ...

  6. Tutorial: Importing and analyzing data from a Web Page using Power BI Desktop

    In this tutorial, you will learn how to import a table of data from a Web page and create a report t ...

  7. Android WebView常见问题的解决方案总结----例如Web page not available

    之前android虚拟机一直都可以直接联网,今天写了一个WebView之后,突然报出了Web page not available的错误,但是查看虚拟机自带的浏览器,是可以上网的,所以检查还是代码的问 ...

  8. LR实战之Discuz开源论坛——网页细分图结果分析(Web Page Diagnostics)

    续LR实战之Discuz开源论坛项目,之前一直是创建虚拟用户脚本(Virtual User Generator)和场景(Controller),现在,终于到了LoadRunner性能测试结果分析(An ...

  9. Home | eMine: Web Page Transcoding Based on Eye Tracking Project Page

    Home | eMine: Web Page Transcoding Based on Eye Tracking Project Page The World Wide Web (web) has m ...

随机推荐

  1. 让人蛋疼的“Oracle.DataAccess.dll”

    项目介绍:为前台网站提供rest接口来操作erp相关数据 涉及db:oracle11 技术方案:因为erp是用remoting来调用,我想rest实现部分调用remoting来操作减少耦合,当然性能上 ...

  2. TP中登录验证

    loginpro 1.建立控制器 loginController.calss.php <?php namespace Admin\Controller; header('Content-type ...

  3. SQL Sever 学习系列之三

    SQL Sever 学习系列之三 SQL Server 学习系列之一(薪酬方案+基础) SQL Server 学习系列之二(日期格式问题)         五.经理今天刚谈到with的用法(with的 ...

  4. Eclipse jar包源码下载

    在使用intelliJ的时候,可以在IDE中直接下载jar包: Eclipse也可以!就是插件Java Source Attacher 这个插件是放在eclipse安装目录的dropins目录下.重启 ...

  5. BZOJ4605:崂山白花蛇草水

    浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...

  6. BZOJ1293:[SCOI2009]生日礼物

    浅谈队列:https://www.cnblogs.com/AKMer/p/10314965.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?i ...

  7. java编程思想第五章初始化与清理

    5.1使用构造器确保初始化: 构造器与一般方法一样,但是没有返回值,且其方法名与类名完全相同. 不接受任何参数的构造器成为默认构造器,也叫无参构造器. 5.2 方法重载: 为什么会有方法重载? 构造器 ...

  8. linux下的时间

    1.linux下时间管理机制: 在系统启动时,Linux操作系统将时间从CMOS中读到系统时间变量中,以后修改时间通过修改系统时间实现.为了保持系统时间与CMOS时间的一致性,Linux每隔11分钟会 ...

  9. 四川第七届 I Travel(bfs)

    Travel The country frog lives in has nn towns which are conveniently numbered by 1,2,…,n1,2,…,n. Amo ...

  10. Redis value的5种类型及常见操作

    Redis本身存储就是一个hash表,实际实࣫比hash表更复一些,后续讲存储结构时会细讲Key只有String类型Value包括String ,Set,List,Hash,Zset五中类型 STRI ...