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

用户阶段
- 合成 URL:用户输入 URL,浏览器会根据用户输入的信息判断的信息是搜索还是网址,如果是搜素内容,就将搜索内容+默认搜索默认搜索引擎合成新的 URL 如果用户输入的内容符合 URL 规则,浏览器就会根据 URL 协议,在这段内容上加上协议合成 URL
- 加载:用户输入完内容,按下回车键,浏览器导航栏显示 loading 状态,但是页面还是呈现前一个页面,这是因为新页面的响应数据还没有获得
![]()
发送 URL 请求阶段
- 构建请求:浏览器进程首先会构建请求行信息,然后通过进程间通信(IPC)将 URL 请求发送给网络进程。
- 查找缓存:网络进程获取到 URL,先去本地缓存中查找是否有缓存资源,如果有则拦截请求,直接将缓存资源返回给浏览器进程;否则,进入网络请求阶段。
- DNS 解析:网络进程请求首先会从 DNS 数据缓存服务中查找是否缓存过当前域名信息,有则直接返回;否则,会进行 DNS 解析返回域名对应 IP 和端口号,如果没有指定端口,http 默认 80 端口 http 默认 443。如果是 https 请求,还需要建立 TLS 连接
- 等待 TCP 队列:Chrome 有个机制,同一个域名同时最多只能建立 6 个 TCP 连接,如果在同一个域名下同时有 10 个请求发生,那么其中 4 个请求会进入排队等待状态,直至进行中的请求完成。如果当前请求数量少于 6 个,会直接建立 TCP 连接;
- 建立 TCP 连接 TCP 三次握手与服务器建立,然后数据的传输
- 发送 HTTP 请求:浏览器首先回向服务器发送行,他包含了请求方法,请求 URI 和 HTTP 协议的版本;另外还会发送请求头,告诉服务器一些浏览器的相关信息,比如浏览器内核,请求域名,Cookie 等如果需要传递参数,则还需要发送请求体
- 服务器处理请求:服务器首先返回响应行,包含协议版本和状态码,比如状态 200 表示继续处理该请求(如果是 301,则表示重定向,将会在响应头的 Location 字段中加上重定向的地址信息,比如服务器生成返回数据的时间,返回的数据类型(JSON HTML 流媒体等类型),以及服务器要在客户端保存的 Cookie 等继续发送响应体的数据
- 断开 TCP 连接:数据传输完成,正常情况下 TCP 将四次握手断开连接。但是浏览器或者服务器在 HTTP 头加上 Connection:keep-alive,TCP 将会一直保持连接。保持 TCP 连接可以省下下次需要建立连接的时间,提示资源加载速度;
准备渲染进程阶段
- 网络进程将获取的数据包进行解析,根据响应头中 Content-type 来判断响应数据的类型,如果是字节流类型,就将该请求交给下载管理器,该导航流程结束,不在进行;如果是 text/html 类型,就通知浏览器进程获取到的是 HTML,应该准备渲染进程了。
- 正常情况下每个浏览器的 tab 会对应一个渲染进程,但如果从一个页面打开了另一个新页面,而新页面和当前页面数据同一个站点的话,那么新页面会复用父页面的渲染进程,否则就会创建一个新的渲染进程。
提交文档阶段
- 渲染进程准备好后,浏览器发出”提交文档“的消息给渲染进程,渲染进程收到消息后,会和网络进程建立传输数据的”管道“,文档数据传输完成后,渲染进程会返回”确认消息“的消息给浏览器进程。
- 浏览器收到”确认消息“的消息后,会更新浏览器的页面状态,包含安全状态地址 URL,前进后退的历史状态,并更新 web 页面,此时 web 页面是空白页
页面渲染阶段

- 文档一旦提交,渲染进程将开始页面解析和资源加载;渲染阶段比较复杂,所以将分为多个子阶段,按照渲染的时间顺序可以分为构建 DOM 树,样式计算,布局阶段,分层,绘制,分块,光栅化和合成
- 构建 DOM 树 HTML 经过解析输出一个 document 为顶层阶段的树形结构 DOM
- 样式计算:这里有 3 个步骤
- 将 3 个来源 link 标签引入的外部样式 style 标签里定义的样式,以及元素的 style,树形上样式 的 CSS 转化成浏览器能够理解的结构 styleSheets
- 转换样式表的属性值,使其标准化;比如
font-weight:bold会转成font-wight:700,color:blue转换成color:rbg(0,0,255)等 - 依据 CSS 的继承和层叠规则计算出 DOM 树种每个节点的具体样式
- 布局阶段 DOM 树种依然存在许多不可见的元素(比如 head),这些元素对于布局是丝毫没用的,所以又会生成一棵只包含可见元素布局树,然后在根据布局树的每个节点计算出其具体位置和尺寸大小
- 分层页面中有很多复杂的效果,比如一些复杂的 3D 变换,页面滚动,或者使用 z-index 做 z 轴排序等,为了更加方便的实现这些效果,渲染引擎还需要为特定的节点生成专用的图层并生成一棵对应的图层树
- 绘制:为每个图层生成绘制列表,并将其提交到合成线程
- 光栅化:通常一个页面很大视口很局限,所以合成线程会按照视口附近的土块来优先生成位图,并在光栅化线程将图块转为位图
- 合成:一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令 DrawQuad,然后将该命令提交给浏览器进程,之后浏览器将开始生成显示页面。


浙公网安备 33010602011771号