从输入URL到页面展示中间发生了什么

这是前端面试最常见的一道题,从输入URL到页面展示,这中间发生了什么?

在开始之前,我们先了解一下HTTP请求流程,下面是一个大体的流程:

  1. 构建请求
    构建请求行信息
  2. 查找缓存
    如果有请求的资源则拦截请求,返回资源,如果没有则继续请求。
  3. 准备IP地址和端口号
    在网络请求之前,我们要建立TCP连接。因为HTTP其实就是把请求的文本信息封装起来,依靠TCP/IP传输。
    建立TCP连接之前还需要IP地址和端口号。那这些又怎么来呢,就需要DNS域名解析。通常DNS域名解析也会被浏览器缓存。
  4. 等待TCP队列
    当我们拿到了IP地址和端口号我们就可以建立TCP连接了吗?NO!!因为Chrome浏览器有一个规定就是,同一域名只能同时建立6个TCP连接。如果当前域名下同时有超过6个请求发生,那么就会进入等待状态。
  5. 建立TCP连接
    通过“三次握手”建立连接。
  6. 发送HTTP请求
    一旦建立连接,浏览器就可以和服务器端通信了。就可以发送HTTP请求了。首先发送请求行。
  7. 服务器处理请求
  8. 服务器响应请求
  9. 断开TCP连接
    通常服务器向客户端返回了请求数据之后就要关闭TCP连接。不过如果在浏览器或服务器头部加了Conection:Keep-Alive TCP连接就会保持打开状态。这样不需要重新建立TCP连接,可以提升资源加载速度。

下面是HTTP请求的流程图:
在这里插入图片描述

还有两个常见问题:

  1. 为什么很多站点第二次打开速度很快?
    缓存!!
    那么哪些数据会被缓存?
    DNS缓存和页面资源缓存这两块数据是会被浏览器缓存的。
    其中DNS缓存就是浏览器本地保留IP地址和域名的对应关系
    页面资源缓存

    • 浏览器端通过响应头cache-control来设定是否缓存
    • 通过Max-age参数设置缓存生存期
    • 若过期则重新请求,请求头代If - None - Match
    • 若未更新则返回304 相当于服务器告诉浏览器此缓存可用
  2. 登录状态是如何保持的?
    Cookie!!!
    如果响应头有Set-Cookie,浏览器会将此保存到本地,在下次请求的时候自动加入Cookie值,然后服务器会对比服务器上的记录,然后得到该用户的状态信息。


    一道华丽的分割线

    从输入URL到页面展示中间发生了什么?

    用户输入

    1. 输入URL并按回车
    2. 浏览器进程检查URL并构成完整的URL(浏览器进入加载状态)

    URL请求

    1. 浏览器进程通过IPC(进程间通信)把URL请求发送给网络进程。(这里的URL请求就是构建成请求行)
    2. 网络进程接收到URL请求首先查看缓存。若有缓存,则返回缓存资源,不再请求,若没有,则发送请求
    3. 发送http请求(http请求其实就是把请求信息封装起来,通过TCP/IP传输)
      5.1 DNS域名解析找到IP地址和端口号(一般HTTP协议默认端口号80)
      5.2 等待TCP队列(如果同一站点同一时刻请求超过6个则等待)
      5.3 建立TCP连接(三次握手)
      5.4 发送HTTP请求
      5.5 网络进程接收响应头和响应数据
    4. 网络进程解析响应流程
      6.1 检查状态码 如果是301/302则需要重定向(301是永久性重定向,浏览器会自己缓存)从Location自动读取地址,重新进行第四步。
      6.2 200响应处理 检查Content-type 如果是字节流 就把请求提交给下载管理器 如果是html则通知浏览器进程准备渲染进程。

    准备渲染进程

    1. 准备渲染进程
      浏览器进程检查当前url和之前打开的渲染进程的根域名是否相同,若相同则复用原来的进程,若不同,则开启新的渲染进程。

    传输数据更新状态

    1. 传输数据 更新状态
      8.1 浏览器进程向渲染进程发起“提交文档”的消息
      8.2 渲染进程收到“提交文档”消息后,会与网络进程建立传输管道,进行数据传输。
      8.3 当渲染进程接收完数据后,会给浏览器进程发送“确认提交”
      8.8 浏览器进程收到“确认提交”后更新页面状态(移除旧文档,导航历史状态)

    渲染阶段

    1. 渲染阶段
      9.1 构建DOM树 (输入HTML 输出DOM树)
      因为浏览器不能直接理解和使用HTML,所以要转化为浏览器能直接理解的结构
      9.2 样式计算 (输入CSS 输出 DOM树中元素样式)

       9.2.1  CSS -> stylesheet
       9.2.2  属性值标准化 (比如长度为px 颜色为rgb)
       9.2.3  计算DOM树中每个节点的具体样式(CSS继承规则 CSS样式层叠规则)
      

      9.3 布局阶段(输入布局树 输出布局树)

       9.3.1 创建可见元素的布局树
       9.3.2 布局计算(计算出可见元素的几何位置)
      

      9.4 分层创建分层树(浏览器页面其实被分成了很多图层)

       要怎么样的节点才会创建新图层?
       拥有层叠上下文属性的元素,比如明确定位属性的,定义透明属性的
       需要剪裁的地方也会被创建为图层
      

      9.5 为每个图层生成绘制列表,并将其提交到合成线程
      输入图层树 输出绘制列表

      9.6 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图

      9.7 合成线程发送绘制图块命令 DrawQuad 给浏览器进程

      9.8 浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上

最后附上流程图(没有渲染流程的):
在这里插入图片描述


相关概念

  • 重排
    更新元素的几何属性
    重排需要更新完整的渲染流水线,所以开销也是最大的

  • 重绘
    更新元素的绘制属性
    重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值