We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在网络世界,你肯定记得住网站的名称,但是很难记住网站的 IP 地址,因而也需要一个地址簿,就是 DNS 服务器。DNS 服务器是高可用、高并发和分布式的,它是树状结构,如图:
DNS的域名查找,在客户端和浏览器,本地DNS之间的查询方式是递归查询;在本地DNS服务器与根域及其子域之间的查询方式是迭代查询;
递归过程:
在客户端输入 URL 后,会有一个递归查找的过程,从浏览器缓存中查找->本地的hosts文件查找->找本地DNS解析器缓存查找->本地DNS服务器查找,这个过程中任何一步找到了都会结束查找流程。
结合起来的过程,可以用一个图表示:
首先,判断是不是https的,如果是,则HTTPS其实是HTTP + SSL / TLS 两部分组成,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
浏览器渲染过程:
为了构建渲染树,浏览器主要完成了以下工作:
第一步中,既然说到了要遍历可见的节点,那么我们得先知道,什么节点是不可见的。不可见的节点包括: 一些不会渲染输出的节点,比如 script、meta、link等。 一些通过css进行隐藏的节点。比如display: none。注意,利用 visibility 和 opacity 隐藏的节点,还是会显示在渲染树上的。只有 display: none 的节点才不会显示在渲染树上。 注意:渲染树只包含可见的节点
第一步中,既然说到了要遍历可见的节点,那么我们得先知道,什么节点是不可见的。不可见的节点包括:
script
meta
link
display: none
visibility
opacity
注意:渲染树只包含可见的节点
浏览器加载JavaScript脚本,主要通过<script>元素完成。其正常流程如下
<script>
加载外部脚本时,浏览器会暂停页面渲染,等待脚本下载并执行完成后,再继续渲染。原因是 JavaScript 代码可以修改 DOM,所以必须把控制权让给它,否则会导致复杂的线程竞赛的问题。
浏览器解析到包含defer属性的<script>元素时,其运行流程如下
deferred
DOMContentLoaded
使用defer属性时需要注意的点:
</html>
document.write
浏览器解析到包含async属性的<script>元素时,其运行流程如下
使用async属性时需要注意的点:
一图胜千言: 原图地址
<script>元素还可以动态生成,生成后再插入页面,从而实现脚本的动态加载。动态生成的script标签不会阻塞页面渲染,也就不会造成浏览器假死。但是问题在于,这种方法无法保证脚本的执行顺序,哪个脚本文件先下载完成,就先执行哪个。如果想避免这个问题,可以设置async属性为false。还可以监听脚本的onload事件来为脚本指定回调。
onload
因为JS脚本可能会引用DOM的样式做计算,所以为了保证脚本计算的正确性,Firefox浏览器会等到脚本前面的所有样式表,都下载并解析完,再执行脚本;Webkit则是一旦发现脚本引用了样式,就会暂停执行脚本,等到样式表下载并解析完,再恢复执行。
此外,对于来自同一个域名的资源,比如脚本文件、样式表文件、图片文件等,浏览器一般有限制,同时最多下载6~20个资源,即最多同时打开的 TCP 连接有限制,这是为了防止对服务器造成太大压力。如果是来自不同域名的资源,就没有这个限制。所以,通常把静态文件放在不同的域名之下,以加快下载速度。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
浏览器请求与服务器响应
DNS 域名解析
在网络世界,你肯定记得住网站的名称,但是很难记住网站的 IP 地址,因而也需要一个地址簿,就是 DNS 服务器。DNS 服务器是高可用、高并发和分布式的,它是树状结构,如图:
DNS的域名查找,在客户端和浏览器,本地DNS之间的查询方式是递归查询;在本地DNS服务器与根域及其子域之间的查询方式是迭代查询;
递归过程:
在客户端输入 URL 后,会有一个递归查找的过程,从浏览器缓存中查找->本地的hosts文件查找->找本地DNS解析器缓存查找->本地DNS服务器查找,这个过程中任何一步找到了都会结束查找流程。
结合起来的过程,可以用一个图表示:
建立TCP连接
首先,判断是不是https的,如果是,则HTTPS其实是HTTP + SSL / TLS 两部分组成,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
浏览器渲染过程
浏览器渲染过程:
生成渲染树
为了构建渲染树,浏览器主要完成了以下工作:
浏览器加载JavaScript脚本
正常加载流程
浏览器加载JavaScript脚本,主要通过
<script>
元素完成。其正常流程如下<script>
标签,呈现引擎移交控制权给Javascript引擎(例如chrome的V8)<script>
标签引用了外部脚本那就先下载再执行,否则直接执行代码defer属性
浏览器解析到包含defer属性的
<script>
元素时,其运行流程如下<script>
标签,继续解析HTML,同时并行下载外链脚本deferred
模式的脚本DOMContentLoaded
事件随之触发使用defer属性时需要注意的点:
DOMContentLoaded
事件触发前执行(即刚刚读取完</html>
标签)document.write
方法async属性
浏览器解析到包含async属性的
<script>
元素时,其运行流程如下<script>
标签,继续解析HTML,让另一进程同时并行下载外链脚本使用async属性时需要注意的点:
document.write
方法async、defer与不加的区别
一图胜千言: 原图地址
脚本的动态加载
<script>
元素还可以动态生成,生成后再插入页面,从而实现脚本的动态加载。动态生成的script标签不会阻塞页面渲染,也就不会造成浏览器假死。但是问题在于,这种方法无法保证脚本的执行顺序,哪个脚本文件先下载完成,就先执行哪个。如果想避免这个问题,可以设置async属性为false。还可以监听脚本的onload
事件来为脚本指定回调。CSS阻塞JS加载
因为JS脚本可能会引用DOM的样式做计算,所以为了保证脚本计算的正确性,Firefox浏览器会等到脚本前面的所有样式表,都下载并解析完,再执行脚本;Webkit则是一旦发现脚本引用了样式,就会暂停执行脚本,等到样式表下载并解析完,再恢复执行。
此外,对于来自同一个域名的资源,比如脚本文件、样式表文件、图片文件等,浏览器一般有限制,同时最多下载6~20个资源,即最多同时打开的 TCP 连接有限制,这是为了防止对服务器造成太大压力。如果是来自不同域名的资源,就没有这个限制。所以,通常把静态文件放在不同的域名之下,以加快下载速度。
DOMContentLoaded 与 load 的区别
参考资料
The text was updated successfully, but these errors were encountered: