浏览器渲染页面常见问题

113 阅读3分钟

什么是 DNS?

当我们在浏览器输入 baidu.com 的时候,浏览器会询问操作系统,是否有关于 baidu.com 这个域名所对应的 IP 信息的缓存,如果操作系统发现没有,那么操作系统会询问ISP 网络供应商(电信、联通),那么供应商会返回相应的 IP 信息,再由操作系统告知给浏览器。这种根据域名查询出 IP 的服务,就叫 DNS。其中查询过程中,浏览器、操作系统,都会有自己的缓存。

什么是三次握手?

三次握手是 TCP 连接建立时的一个步骤,假如 A 是浏览器,B 是服务器:

  1. A 向 B 发送一个 SYN(X) SYN 是 synchronize 的缩写,X 是一个数字。
  2. B 在接收到这个信息后,会发送一个 ACK(X+1)SYN(Y) ACK 是 acknowledge 的缩写,Y 是一个新的数字。由于 B 可能会收到多条 SYN 信息,所以它发送的 ACK 是在 X 的基础上加 1。
  3. A 接收到这个消息后,会再向 B 发送一个 ACK(Y+1)
  4. 此时 A 向 B 发送 HTTP 内容。

通过三次握手,能确定下面这些事情:

  1. A 可以向 B 发送信息,且 B 可以收到 A 的信息。
  2. B 可以向 A 发送信息,且 A 可以收到 B 的信息。

当三次握手成功后,那么此时就可以正常建立 TCP 连接了,通常就是传输 HTTP 内容。

什么是四次挥手?

四次挥手是 TCP 连接关闭时的一个步骤,假如 A 是浏览器,B 是服务器:

  1. A 向 B 发送一个 FIN(X),FIN 是 finish 的缩写,X 是一个数字。
  2. B 接收到这个信息后,会发送一个 ACK(X+1)
  3. B 如果确定自己也可以断开了,则会继续发送一个 FIN(Y)
  4. A 接收到这个信息后,会发送一个 ACK(Y+1)

一般来说,如果经历了这 4 个步骤,那么双方可以安全地关闭连接。

浏览器是怎么把 html 渲染成页面的?

假设我们有这样的 html 内容:

<link href="xxx">
<h1>你好</h1>
<script src="xxx" />
<div>更多</div>

浏览器会边下载边解析 HTML 内容,遇到 link 标签,则会开始下载 css 文件,此时会继续往下解析,同时 css 文件也是处于边下载边解析的状态,不过要注意的是:这个阶段,浏览器并不会直接渲染 h1 标签,而是先构建 DOM 树,css 的解析同理,也是在构建 css 树。如果中途遇到了 script 标签,则解析 html 是需要停下来的,必须要等 js 文件下载并执行完后再继续。

当 html 树以及 css 树都解析完毕后,浏览器则会将两者结合,得到一个渲染树。之后浏览器会依次执行这几个步骤:

  1. 布局(layout):计算元素的大小、尺寸。
  2. 绘制(paint):填充元素颜色、边框、阴影。
  3. 合成(composite):因为页面上可能有元素是重叠的,有上下关系(z-index),所以需要处理。

script 标签上的 async 和 defer 有什么区别?

  • defer:当遇到这个 script 标签时,仍然会去下载这个文件,但是不阻塞 html 解析,下载完毕后等 html 全部解析完了之后再执行,注意:等这个 js 执行完后,才会触发 document.ready 事件。如果有多个 defer 标签,执行顺序仍然是按照 script 的标签顺序。
  • async:和 defer 基本一致,但是不会阻塞 document.ready 事件。如果有多个 async 标签,执行顺序是不保证的。

什么是 reflow 和 repaint?

reflow 是回流,指的是重新 布局(layout) 的意思,repaint 是重绘,值得是重新 绘制(paint) 的意思。简单来说,有些属性会造成回流,有些属性会造成重绘,还有属性是两者都会触发,比如改变元素的高度,那么就只会回流,如果改变元素的颜色,则只会重绘,不过这些步骤之后,都需要进行合成。具体的规则,可以参考csstriggers

TODO