你不知道的浏览器渲染原理(详细攻略)

你不知道的浏览器渲染原理(详细攻略)

Scroll Down

浏览器渲染过程

当输入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连接。加密大致过程:

  1. 客户端发起请求,向服务端索要并验证公钥
  2. 双方协商生成“对话密钥”
  3. 双方采用”对话密钥“进行加密通信

b)TCP三次握手过程是:**

  1. 查找到IP后向服务器发起连接请求,这个阶段是TCP三次握手的过程,简要来说是:客户端发送SYN=1,Seq=x请求服务端连接,服务端收到信息向客户端发送SYN=1,ACK=1(确认包),ACKNum=x+1,Seq=y,客户端收到服务端的确认信息,回复ACK=1,ACKNum=y+1表示确认服务端的确认连接。
  2. 客户端发起Http请求,包括请求行(请求方法,url,协议版本号),请求头(cookietaken),请求体(包括参数)
  3. 服务端响应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, 并打开浏览器查看

1595556747742.png

发现灰色加载阶段html文件已经解析完成了, bootstrap.css并还没有阻塞html的解析,所以得出结论: CSS加载并不阻塞DOM树的解析

1595556982136.png

那我们继续思考: CSS加载阻塞DOM树的渲染吗?, 其实这个问题从浏览器渲染机制就能看出, 因为CSS本来就是render树的属性,所以肯定需要完成CSS加载完成后才渲染DOM (即render树). 所以得出结论: CSS加载会阻塞DOM树的渲染

Q: 如何CSS加载会影响DOM树渲染,那么会影响JS执行吗?

大胆猜测一下,如图:

1595557770468.png

解释一下:如果CSS加载会阻塞JS执行的话,那么loading的时间间隔肯定就是CSS加载的时间,否则就不会阻塞JS的执行

那么看结果:

1595558200869.png

1595558136609.png
所以得出结论:CSS加载会阻塞JS执行

什么是图层、图块、位图?页面如何显示的?

  • **图层:**也叫层叠上下文,对于浏览器而言,不可能一次性渲染整个页面,因为这样会导致某些加载比较快的区域已经完成,但加载慢的却还在加载中,导致整个页面渲染性能很低。所以浏览器会将具有特定属性值的元素作为单独的一个图层单独渲染后再按照合理的顺序合并成一个图层,然后显示再屏幕上。

image.png

​ 成为新图层的条件:

  • position值为absolute或relative且z-index值不为auto的元素

  • position值为fixed或sticky的元素

  • flex容器的子元素,且z-index不为auto

  • opacity不为1的元素

  • transform/filter属性不为none的元素

  • will-change设定为任意值(会调用GPU加速,可用于加载动画)

  • 需要剪裁的地方也会被创建成新图层

    Example of stacking rules modified using z-index

  • **图块:**浏览器会根据屏幕(视口)分割整个页面为多个图块,当用户滑动页面时,会加载视口附件的图块,图块转换成位图的过程叫做光栅化

  • **位图:**合成线程会按照视口附件的图块调用光栅化线程池来优先生成位图。渲染进程维护了一个栅格化的线程池,使用GPU生成位图。

  • **合成和显示:**一旦所有图块都被光栅化,合成线程生成一个绘制图块的命令,然后提交给浏览器进程,浏览器进程调用viz组件,根据绘制命令绘制到内存,最终显示在屏幕上

img

未完待续....... (下一期闭包、this、作用域总结)