How a web page loads
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:
- If the script is external its source must be fully downloaded.
- 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的更多相关文章
- [转]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 ...
- 解读Web Page Diagnostics网页细分图
解读Web Page Diagnostics网页细分图 http://blog.sina.com.cn/s/blog_62b8fc330100red5.html Web Page Diagnostic ...
- 网页细分图结果分析(Web Page Diagnostics)
Discuz开源论坛网页细分图结果分析(Web Page Diagnostics) 续LR实战之Discuz开源论坛项目,之前一直是创建虚拟用户脚本(Virtual User Generator)和场 ...
- Atitit.web三大编程模型 Web Page Web Forms 和 MVC
Atitit.web三大编程模型 Web Page Web Forms 和 MVC 1. 编程模型是 Web Forms 和 MVC (Model, View, Controller). 2. ...
- [转]Calling Web Service Functions Asynchronously from a Web Page 异步调用WebServices
本文转自:http://www.codeproject.com/Articles/70441/Calling-Web-Service-Functions-Asynchronously-from Ove ...
- 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 ...
- Android WebView常见问题的解决方案总结----例如Web page not available
之前android虚拟机一直都可以直接联网,今天写了一个WebView之后,突然报出了Web page not available的错误,但是查看虚拟机自带的浏览器,是可以上网的,所以检查还是代码的问 ...
- LR实战之Discuz开源论坛——网页细分图结果分析(Web Page Diagnostics)
续LR实战之Discuz开源论坛项目,之前一直是创建虚拟用户脚本(Virtual User Generator)和场景(Controller),现在,终于到了LoadRunner性能测试结果分析(An ...
- 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 ...
随机推荐
- java-10异常处理动手动脑
1.请阅读并运行AboutException.java示例,然后通过后面的几页PPT了解Java中实现异常处理的基础知识. import javax.swing.*; class AboutExcep ...
- 六、python沉淀之路--int str list tuple dict 重点总结
一.数字int(..)二.字符串replace/find/join/strip/startswith/split/upper/lower/formattempalte = "i am {na ...
- keepalived 检测脑裂切换脚本
#!/bin/bash count=0 run1=`curl -I 192.168.30.12:8000 | grep "200 OK" | wc -l` run2=`curl - ...
- 用python的for循环写冒泡排序
题目:利用for循环,完成a=[1,7,4,89,34,2]的冒泡排序(冒泡排序:小的排前面,大的排后面.) 第一种:可以看到每次排序的结果 a = [100,97,4,89,34,2] n = 0 ...
- 如何解决SSH登录Solaris主机速度慢的问题
SSH登录速度慢可能有多种原因. 1. 与DNS有关 缺省情况下,当客户端用SSH登录solaris服务器时,服务器会试图反向解析客户端的IP 地址(即把IP地址解析成机器名).如果Solaris系统 ...
- java 多线程系列---JUC原子类(三)之AtomicLongArray原子类
AtomicLongArray介绍和函数列表 在"Java多线程系列--“JUC原子类”02之 AtomicLong原子类"中介绍过,AtomicLong是作用是对长整形进行原子操 ...
- AOP基础-JDK动态代理
动态代理技术就是用来产生一个目标对象的代理对象的,代理对象应与目标对象(被代理的对象)有相同的方法,实现对目标对象访问的拦截,并增强目标对象的一些功能,而不需要目标对象去做任何的更改,使得目标对象有更 ...
- 基于Flask框架的Python web程序的开发实战 <一> 环境搭建
最近在看<Flask Web开发基于Python的Web应用开发实战>Miguel Grinberg著.安道译 这本书,一步步跟着学习Flask框架的应用,这里做一下笔记 电脑只安装一个P ...
- ssh框架搭建实例代码教程步骤
http://blog.csdn.net/u010539352/article/details/49255729
- ListView里面嵌套CheckBox
布局文件 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:andro ...