必会面试题!浏览器从输入一个URL到页面显示,发生了什么

62 阅读7分钟

1. 浏览器从输入一个URL到网页展示出来,到底发生了什么

1.1. DNS服务器解析的过程

DNS( Domain Name System )

当你在浏览器中输⼊⼀个URL⽐如www.example.com 时,我们需要先找到它对应的IP地址:这个过程被称为DNS 解析,即域名系统解析。

输入一个URL后,我们需要先找到它的ip地址,所以要先进行DNS解析,在DNS解析过程中,浏览器会先查找缓存,先查找浏览器缓存,浏览器会先检查它的缓存中是否有这个域名的记录,如果有的话就直接访问该ip地址,没有的话,会查找操作系统缓存,因为操作系统中也可能有自己的DNS缓存,如果也没有找到,请求会发到本地网络的路由器中,在路由器中查找缓存,如果还没有找到,请求最终会发送到ISP也就是互联网服务提供商,它们通常会有更大范围的DNS缓存。
如果都没有缓存,就对DNS进行递归解析,首先DNS查询会被发送到根域名服务器,根域名服务器是最高级别的服务器,负责重定向到负责管理顶级域名(.com)的顶级域名服务器,(根服务器会告诉你的ISP的DNS服务器去查询哪个顶级域名服务器来找到.com域的信息,这个顶级域名服务器掌握所有.com域名以及其相应服务器的信息,一旦DNS服务器找到了正确的顶级域名服务器),它会进一步定位到负责example.com的权威服务器,权威服务器有该url的具体ip地址。最终权威服务器提供www.example.com域名对应的IP地址,这个信息会被发送回用户的电脑,浏览器对该域名进行缓存。

1.2. TCP建立连接过程

TCP (Transmission Control Protocol, 传输控制协议)

image.png

TCP是⼀种⾯向连接的协议,⽤于在⽹络中的两个端点之间建⽴可靠的会话(通道)。

TCP 传输的是字节流

TCP建立连接过程,通常称为三次握手 (TCP 3-way handshake)

  • SYN
  • SYN-ACK
  • ACK

经过上述操作,此时,浏览器完成了对该url的DNS解析,然后本地客户端要向该服务器发送http请求,发送http请求前,为了保证数据传输的可靠性,需要先进行TCP连接.
TCP连接过程要经历三次握手,首先客户端发送一个SYN包到服务器以初始化一个连接,客户端设置一个随机的序列号,告诉服务器它准备开始发送数据,序列号不仅在握手期间使用,在后续的传输数据也会用到。服务器收到客户端的SYN包后,会发送一个SYN-ACK包作为响应,服务器也同样会设置一个随机的序列号,并将客户端的序列号加一,发送回客户端,确认已经收到了客户端的同步请求,客户端收到服务器的SYN-ACK后,发送一个ACK包作为回应,这个包将服务器的序列号加一,并可能包含客户端准备发送的数据的开始部分,比如http请求行和请求头,这个被称为TCP快速打开,此时TCP连接已经建立,双方可以进行http数据传输。

1.3. HTTP请求的过程

再往后,客户端可以通过这个连接发送一个http请求到服务器,这个请求中包含了方法,URL和协议版本,以及可能存在的响应头和响应体。服务器接收到HTTP请求后,会处理这个请求,并返回一个HTTP响应,响应通常包括状态码,响应头,响应体以及一些静态资源,比如index.html,然后浏览器进行渲染

1.4. 资源下载

JavaScript会不会阻塞dom,取决于script标签的设置

1.5. 网页解析和渲染

  1. HTML解析规则

服务器给浏览器返回index.html,所以解析HTML是所有步骤的开始,解析HTML,会构建DOM tree:

  1. 生成CSS规则

在解析index.html的过程中,如果遇到了css的link文件,那么会由浏览器下载对应的CSS文件,下载CSS文件是不会影响到DOMTree的建立的,CSS文件下载后,会对CSS文件进行解析,解析出对应的规则树,可以称之为CSSOM(CSS Object Model)

  1. 构建Render Tree

注意⼀:link元素不会阻塞DOM Tree的构建过程,但是会阻塞Render Tree的构建过程 这是因为Render Tree在构建时,需要对应的CSSOM Tree;

注意⼆:Render Tree和DOM Tree并不是⼀⼀对应的关系,⽐如对于display为none的元素,压根不会出现在 render tree中;

CSSOM和DOM Tree构建完成后,浏览器会将二者结合起来生成Render Tree

  1. 在Render Tree上进行Layout(布局)

然后浏览器将在Render Tree上运行Lay out 以计算每个节点的几何体

  • 渲染树会表示显示哪些节点以及其他样式,但是不表示每个节点的尺寸,位置等信息
  • 布局是确定呈现树中所有节点的宽度、⾼度和位置信息;
  1. 将每个节点paint(绘制)到屏幕上
  • 在绘制阶段,浏览器将lay out阶段计算的每个frame转为屏幕上的实际像素点
  • 包括将元素的可⻅部分进⾏绘制,⽐如⽂本、颜⾊、边框、阴影、替换元素(⽐如img)

1.6. 回流和重绘

1.6.1. 回流(reflow)

回流也可以称为重排

  • 第一次确定节点的大小和位置,称之为布局(layout)
  • 之后对节点的大小,位置修改重新计算称为回流

什么情况会引起回流呢?

  • DOM结构发生变化,增加或者删除节点
  • 改变了布局(修改了width,height,padding,font-size)等值
  • 修改了窗口的尺寸
  • 调用getComputedStyle方法获取尺寸,位置等信息

1.6.2. 重绘 ( repaint )

  • 第一次渲染内容称为绘制(Painting)
  • 之后重新渲染称之为重绘

什么情况下会引起重绘呢?

  • 修改背景色,文字颜色,边框颜色,样式等
  • 修改阴影,box-shadow,text-shadow
  • 修改背景图像,background-image等

回流⼀定会引起重绘,所以回流是⼀件很消耗性能的事情。

如何避免发生回流重绘:

  1. 修改样式时,尽量一次性修改
  2. 通过添加class修改等
  3. 尽量避免频繁操作DOM
  4. 尽量避免通过getComputedStyle获取尺寸,位置等信息
  5. 对某些元素使用position的absolut或者fixed并不是不会引起回流,⽽是开销相对较⼩,不会对其他元素造成影响

1.7. 创建合成层优化

绘制的过程,可以将布局后的元素绘制到多个合成图层中。

这是浏览器的⼀种优化⼿段; 默认情况下,标准流中的内容都是被绘制在同⼀个图层(Layer)中的;

⽽⼀些特殊的属性,会创建⼀个新的合成层( CompositingLayer ),并且新的图层可以利⽤GPU来加速绘制; 因为每个合成层都是单独渲染的;

那么哪些属性可以形成新的合成层呢?

常⻅的⼀些属性:

  • 3D transforms video、canvas、iframe
  • opacity 动画转换时;
  • position: fixed
  • will-change:⼀个实验性的属性,提前告诉浏览器元素可能发⽣哪些变化;
  • animation 或 transition 设置了opacity、transform;

分层确实可以提⾼性能,但是它以内存管理为代价,因此不应作为 web 性能优化策略的⼀部分过度使⽤。

    <style>
      .box1,
      .box2 {
        width: 100px;
        height: 100px;
        background-color: #18f;
      }
      .box2 {
        background-color: #f81;
        will-change: transform;
        /* position: fixed;
        left: 0;
        top: 200px; */
      }
    </style>
  </head>
  <body>
    <div class="box1"></div>
    <div class="box2"></div>
  </body>