浏览器渲染过程
当输入url之后发生了什么?
一、用户输入
首先输入url
按下回车后,浏览器会开始转圈,这个时候会触发beforeunload
事件,该事件能时网页触发一个询问框,询问用户是否离开当前网页。
二、URL请求过程
如果选择离开或者没有监听该事件,就进入了页面请求资源过程。这时,浏览器通过进程间通信(IPC
)把URL请求发送到网络进程,并开始网络请求过程:
**a)查找ip
地址:**首先网络进程会在本地hosts文件查找是否有网站的映射,如果没有则请求本地服务器查看是否包含在本地配置资源中,如果在则返回解析给客户端,完成域名解析。如果没有就往根目录域名解析DNS
,如果再没有找到就根据本地DNS
配置进行递归或迭代查询,最后解析DNS
得到IP
并缓存DNS
。如果https
,还需要建立TLS
连接
什么是
TLS
连接?
TLS
是继SSL
的3.0版本后的新的加密协议。为了使http
连接更加安全可靠,TLS
使用公-密钥的方式在http
中相对普通http
更安全的连接,即https
连接。加密大致过程:
- 客户端发起请求,向服务端索要并验证公钥
- 双方协商生成“对话密钥”
- 双方采用”对话密钥“进行加密通信
b)TCP
三次握手过程是:**
- 查找到
IP
后向服务器发起连接请求,这个阶段是TCP
三次握手的过程,简要来说是:客户端发送SYN
=1,Seq
=x请求服务端连接,服务端收到信息向客户端发送SYN
=1,ACK
=1(确认包),ACKNum
=x+1,Seq
=y,客户端收到服务端的确认信息,回复ACK
=1,ACKNum
=y+1表示确认服务端的确认连接。 - 客户端发起
Http
请求,包括请求行(请求方法,url
,协议版本号),请求头(cookie
,taken
),请求体(包括参数) - 服务端响应
Http
请求,发送应答,响应头,响应数据等
c)浏览器根据服务器发来的数据进行渲染: 根据HTML
文档解析出DOM
树,根据CSS
规则解析出CSSOM
规则树,根据DOM
树和CSSOM
树生成渲染树,合成线程根据渲染树生成图层和图块,合成线程调用光栅化线程池生成位图,使用GPU
加速渲染,最后合成线程调用绘制指令进行绘制并显示到浏览器中
浏览器绘制完成后断开TCP连接。
DOM是如何构建的?
获取到
html
资源后,通过HTMLDocumentParser
类负责解析html
文本为tokens
,借助HTMLTreeBuilder
对这些tokens
分类处理,根据不同标签类、文档不同位置,调用HTMLConstructionSite
不同的函数构建DOM树
**d)TCP的四次挥手:**第一次客户端发出FIN
=1,Seq
=x请求断开连接,第二次服务器发出确认包ACK
=1,ACKNum
=x+1接受客户端关闭的请求,但还没有准备好关闭连接。第三次服务器发出FIN=1,Seq=y向客户端发送断开连接请求,等到客户端发来最后一个ACK
。第四次客户端发出ACK
=1,ACKNum
=y+1,等待可能重传的ACK
,服务端确认关闭后,关闭连接。客户端等待2MSL
后没有收到ACK
,则自己也关闭连接
DNS的两种方式是什么?
A: 有两种方式: ( A: 客户端 B: 本地DNS
服务器 C: 根域名服务器 D:顶级域名服务器)
- 迭代查找:
A查了本地host文件,没有网站映射,就跑去问B, B说: 我不知道, 你去问问C吧! A又跑去问C, C说: 我这里查到了,给你吧! 然后A拿到IP
高兴的回去了
- 递归查找
A查了本地host文件, 没有网站映射, 就跑去问B,B说: 我不知道, 我帮你去问问C吧! B跑去问C, C说: 我这里没有,我帮你去问问D吧,然后在D那里找到了, A就可以完成解析IP
CSS渲染机制
Q: js
执行会阻塞DOM树的解析和渲染, 那么CSS
加载会阻塞DOM树的解析和渲染吗?
A: 首先根据前者大胆猜测一下: CSS
加载会阻塞DOM树的解析和渲染. 那么我们如何来证明这个猜想呢?
实际操作一下
首先我们验证是否会阻塞DOM树的解析:
这里使用link
标签加载bootstrap.css
并将下载输入速度控制为slow 3G, 并打开浏览器查看
发现灰色加载阶段html
文件已经解析完成了, bootstrap.css
并还没有阻塞html
的解析,所以得出结论: CSS加载并不阻塞DOM树的解析
那我们继续思考: CSS加载阻塞DOM树的渲染吗?, 其实这个问题从浏览器渲染机制就能看出, 因为CSS本来就是render
树的属性,所以肯定需要完成CSS加载完成后才渲染DOM (即render
树). 所以得出结论: CSS加载会阻塞DOM树的渲染
Q: 如何CSS加载会影响DOM树渲染,那么会影响JS执行吗?
大胆猜测一下,如图:
解释一下:如果CSS
加载会阻塞JS
执行的话,那么loading
的时间间隔肯定就是CSS
加载的时间,否则就不会阻塞JS
的执行
那么看结果:
所以得出结论:CSS加载会阻塞JS执行
什么是图层、图块、位图?页面如何显示的?
- **图层:**也叫层叠上下文,对于浏览器而言,不可能一次性渲染整个页面,因为这样会导致某些加载比较快的区域已经完成,但加载慢的却还在加载中,导致整个页面渲染性能很低。所以浏览器会将具有特定属性值的元素作为单独的一个图层单独渲染后再按照合理的顺序合并成一个图层,然后显示再屏幕上。
成为新图层的条件:
-
position
值为absolute或relative且z-index
值不为auto的元素 -
position
值为fixed或sticky的元素 -
flex
容器的子元素,且z-index
不为auto -
opacity
不为1的元素 -
transform
/filter
属性不为none的元素 -
will-change
设定为任意值(会调用GPU
加速,可用于加载动画) -
需要剪裁的地方也会被创建成新图层
-
**图块:**浏览器会根据屏幕(视口)分割整个页面为多个图块,当用户滑动页面时,会加载视口附件的图块,图块转换成位图的过程叫做光栅化
-
**位图:**合成线程会按照视口附件的图块调用光栅化线程池来优先生成位图。渲染进程维护了一个栅格化的线程池,使用GPU生成位图。
-
**合成和显示:**一旦所有图块都被光栅化,合成线程生成一个绘制图块的命令,然后提交给浏览器进程,浏览器进程调用viz组件,根据绘制命令绘制到内存,最终显示在屏幕上
未完待续....... (下一期闭包、this、作用域总结)