3

从输入 URL 到页面显示发生了什么

 2 years ago
source link: https://bubuzou.com/2020/12/16/browser-url/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

从输入 URL 到页面显示发生了什么

2020-12-16

读了李兵老师的 浏览器的工作原理与实践,让我对浏览器的工作原理有了更加深刻的理解,尤其是从用户输入 URL 到页面显示这一过程发生的事情,以往看的文章都是点到为止,而他却说得面面俱到非常详细,遂我把内容总结了一下分享给大家,值得你花个 5 分钟阅读一下。

browser_002.png

用户输入阶段

  1. 合成 URL:用户输入 URL,浏览器会根据用户输入的信息判断是搜索还是网址,如果是搜索内容,就将搜索内容 + 默认搜索引擎合成新的 URL;如果用户输入的内容符合 URL 规则,浏览器就会根据 URL 协议,在这段内容上加上协议合成合法的 URL
  2. 加载:用户输入完内容,按下回车键,浏览器导航栏显示 loading 状态,但是页面还是呈现前一个页面,这是因为新页面的响应数据还没有获得;

发起URL请求阶段

browser_001.png

  1. 构建请求:浏览器进程首先会构建请求行信息,然后通过进程间通信(IPC)将 URL 请求发送给网络进程;
  2. 查找缓存:网络进程获取到 URL,先去本地缓存中查找是否有缓存资源,如果有则拦截请求,直接将缓存资源返回给浏览器进程;否则,进入网络请求阶段;
  3. DNS 解析:网络进程请求首先会从 DNS 数据缓存服务中查找是否缓存过当前域名信息,有则直接返回;否则,会进行 DNS 解析返回域名对应的 IP 和端口号,如果没有指定端口号,http 默认 80 端口,https 默认 443。如果是 https 请求,还需要建立 TLS 连接;
  4. 等待 TCP 队列:Chrome 有个机制,同一个域名同时最多只能建立 6 个 TCP 连接,如果在同一个域名下同时有 10 个请求发生,那么其中 4 个请求会进入排队等待状态,直至进行中的请求完成。如果当前请求数量少于6个,会直接建立 TCP 连接;
  5. 建立 TCP 连接:TCP 三次握手与服务器建立连接,然后进行数据的传输,最后;
  6. 发送 HTTP 请求:浏览器首先会向服务器发送请求行,它包含了请求方法、请求 URIHTTP 协议的版本;另外还会发送请求头,告诉服务器一些浏览器的相关信息,比如浏览器内核,请求域名、Cookie 等;如果需要传递参数,则还需要发送请求体;
  7. 服务器处理请求:服务器首先返回响应行,包括协议版本和状态码,比如状态码 200 表示继续处理该请求;(如果是 301,则表示重定向,将会在响应头的 Locaiton 字段中加上重定向的地址信息,接下来浏览器获取这个地址,将会重新导航。)服务器也会向浏览器发送响应头,包含了一些信息,比如服务器生成返回数据的时间、返回的数据类型(JSONHTML、流媒体等类型),以及服务器要在客户端保存的 Cookie 等;继续发送响应体的数据;
  8. 断开 TCP 连接:数据传输完成,正常情况下 TCP 将四次挥手断开连接。但是如果浏览器或者服务器在HTTP头部加上 Connection: keep-aliveTCP 就会一直保持连接。保持 TCP 连接可以省下下次需要建立连接的时间,提示资源加载速度;

准备渲染进程阶段

  1. 网络进程将获取到的数据包进行解析,根据响应头中的 Content-type 来判断响应数据的类型,如果是字节流类型,就将该请求交给下载管理器,该导航流程结束,不再进行;如果是 text/html 类型,就通知浏览器进程获取到的是 HTML,应该准备渲染进程了;
  2. 正常情况下每个浏览器的 tab 会对应一个渲染进程,但如果从一个页面打开了另一个新页面,而新页面和当前页面属于同一站点的话,那么新页面会复用父页面的渲染进程,否则就会创建一个新的渲染进程;

提交文档阶段

  1. 渲染进程准备好后,浏览器会发出 “提交文档” 的消息给渲染进程,渲染进程收到消息后,会和网络进程建立传输数据的 “管道”,文档数据传输完成后,渲染进程会返回“确认提交”的消息给浏览器进程;
  2. 浏览器收到 “确认提交” 的消息后,会更新浏览器的页面状态,包括了安全状态、地址栏的 URL、前进后退的历史状态,并更新 web 页面,此时的 web 页面是空白页;

页面渲染阶段

browser_010.png

  1. 文档一旦提交,渲染进程将开始页面解析和子资源加载;渲染阶段比较复杂,所以将分为多个子阶段,按照渲染的时间顺序可以分为:构建 DOM 树、样式计算、布局阶段、分层、绘制、分块、光栅化和合成;

  2. 构建 DOM 树:HTML 经过解析后输出一个以 document 为顶层节点的树状结构的 DOM

  3. 样式计算:这里有 3 个步骤:

    • 将 3 个来源(<link> 标签引入的外部样式、<style> 标签里定义的样式、以及元素的 style 属性上的样式)的 CSS 转化成浏览器能够理解的结构 styleSheets
    • 转换样式表中的属性值,使其标准化;比如 font-weight: bold; 会转成 font-weight: 700;color: blue; 会转成 color: rgb(0, 0, 255); 等;
    • 依据 CSS 的继承和层叠规则计算出 DOM 树中每个节点的具体样式;
  4. 布局阶段:DOM 树中依然存在许多不可见的元素(比如 head),这些元素对于布局是丝毫没用的,所以又会生成一棵只包含可见元素的布局树;然后再根据布局树的每个节点计算出其具体位置和尺寸大小;

  5. 分层:页面中有很多复杂的效果,如一些复杂的 3D 变换、页面滚动,或者使用 z-index 做 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树;关于层叠上下文的知识,具体可以参考这里彻底搞懂CSS层叠上下文、层叠等级、层叠顺序、z-index

  6. 绘制:为每个图层生成绘制列表,并将其提交到合成线程;

  7. 光栅化:通常一个页面很大,而视口很局限,所以合成线程会按照视口附近的图块来优先生成位图,并在光栅化线程池中将图块转换成位图;

  8. 合成:一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令 DrawQuad,然后将该命令提交给浏览器进程;之后浏览器将开始生成显示页面。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK