浏览器输入 URL 发生了什么
前言
前端工程师几乎每天都要和浏览器打交道,所以,了解浏览器是如何工作的,能够使我们快速定位问题和提升用户体验。
用户输入
地址栏会判断是搜索内容还是请求 URL。
- 如果是搜索内容,地址栏会使用浏览器默认的搜索引擎,来合成新的带搜索关键字的 URL。
- 如果判断输入内容符合 URL 规则,那么地址栏会根据规则,把这段内容加上协议,合成为完整的 URL。
URL 请求过程
- 查找本地缓存是否有资源,如果有就直接获取,没有的话就进入下一步。
- 进行 DNS 解析,以获取请求的 IP 地址。如果协议是 https 还需要进行 TLS 连接。
- IP 地址和服务器的 TCP 连接。
- 建立连接后,发送请求头等信息给服务器。
- 服务器接收到请求信息,将响应头等数据返回给客户端。
- 重定向:网络进程解析响应头,如果状态码 301 或者 302,那么说明重定向到其他 URL,而这个 URL 是 Location 字段值。
- 响应数据类型处理:Content-Type 是 HTTP 头中一个非常重要的字段, 它告诉浏览器服务器返回的响应体数据是什么类型,然后浏览器会根据 Content-Type 的值来决定如何显示响应体的内容。
准备渲染进程
什么是同一站点
- 根域名:极客时间(geekbang.org)。
- 协议:http:// 或 https://。
- 根域名下的所有子域名和不同的端口。
打开一个新页面的渲染进程策略
- 通常情况下,打开新的页面都会使用单独的渲染进程。
- 如果从 A 页面打开 B 页面,且 A 和 B 都属于同一站点的话,那么 B 页面复用 A 页面的渲染进程;如果是其他情况,浏览器进程则会为 B 创建一个新的渲染进程。
提交文档
- 网络进程告知浏览器进程,可以让渲染进程过来取资源了。
- 浏览器进程通知渲染进程,渲染进程打开与网络进程之间的传输通道,等所有资源都传输完后,渲染进程通知浏览器进程。
- 浏览器进程收到渲染进程的提交完成信息后,就开始更新安全状态、地址栏的 URL、前进后退的历史状态,并更新 Web 页面。
渲染阶段
构建 DOM 树
这是因为浏览器无法直接理解和使用 HTML,所以需要将 HTML 转换为浏览器能够理解的结构——DOM 树。
样式计算
- 把 CSS 转换为浏览器能够理解的结构——styleSheets。
- 转换样式表中的属性值,使其标准化。即浏览器需要将 css 的所有属性值转换为渲染引擎容易理解的、标准化的计算值。
- 计算出 DOM 树中每个节点的具体样式,运用继承规则和层叠规则。
总之,样式计算阶段的目的是为了计算出 DOM 节点中每个元素的具体样式,在计算过程中需要遵守 CSS 的继承和层叠两个规则。这个阶段最终输出的内容是每个 DOM 节点的样式,并被保存在 ComputedStyle 的结构内。
布局阶段
计算出 DOM 树中可见元素的几何位置,我们把这个计算过程叫做布局。
- 创建布局树:遍历 DOM 树中的所有可见节点,并把这些节点加到布局树中,而不可见的节点会被布局树忽略掉。
- 布局计算
分层
因为页面中有很多复杂的效果,如一些复杂的 3D 变换、页面滚动,或者使用 z-indexing 做 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树。
通常情况下,并不是布局树的每个节点都包含一个图层,如果一个节点没有对应的层,那么这个节点就从属于父节点的图层。
创建新图层的条件:
- 拥有层叠上下文属性的元素会被提升为单独的一层:明确定位属性的元素、定义透明属性的元素、使用 CSS 滤镜的元素等,都拥有层叠上下文属性。
- 需要剪裁(clip)的地方也会被创建为图层。
图层绘制
绘制一个元素通常需要好几条绘制指令,因为每个元素的背景、前景、边框都需要单独的指令去绘制。所以在图层绘制阶段,输出的内容就是这些待绘制列表。
栅格化操作
我们把用户可以看到的这个部分叫做视口。
有的图层很大,这时候为了减少渲染引擎不必要的开销,合成线程会将图层划分为图块。
维基百科:位图(英语:Bitmap,台湾称为点阵图),又称栅格图(Raster graphics),是使用像素阵列(Pixel-array/Dot-matrix点阵)来表示的图像。
合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图。可以理解为在视口呈现的图像。
合成和显示
一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。浏览器进程里面有一个叫 viz 的组件,用来接收合成线程发过来的 DrawQuad 命令,然后根据 DrawQuad 命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上。到这里,经过这一系列的阶段,编写好的 HTML、CSS、JavaScript 等文件,经过浏览器就会显示出漂亮的页面了。
渲染阶段总结一张图如下:
扩展:渲染阶段
什么是重排
重排是在网络浏览器中执行的一个流程,用于重新计算文档中各元素的位置和几何形状,以便重新呈现该文档的部分内容或全部内容。
重排需要更新完整的渲染流水线,所以开销也是最大的。
触发重排的操作
- 页面首次渲染,这是开销最大的一次重排。
- 浏览器窗口尺寸改变。
- 元素位置和尺寸发生改变。
- 新增和删除可见元素。
- 内容发生改变(文字数量或图片大小等等)。
- 元素字体大小变化。
- 激活 css 伪类(:hover)。
- 设置 style 属性。
- 查询某些属性或调用某些方法:offsetWidth、offsetHeight 等,除此之外,当我们调用 getComputedStyle 方法,或者 IE 里的 currentStyle 时,也会触发重排,原理都是求一个“即时性”和“准确性”。
常见引起重排属性和方法如下:
width
height
margin
padding
display
border-width
border
position
overflow
font-size
vertical-align
min-height
clientWidth
clientHeight
clientTop
clientLeft
offsetWidth
offsetHeight
offsetTop
offsetLeft
scrollWidth
scrollHeight
scrollTop
scrollLeft
scrollIntoView()
scrollTo()
getComputedStyle()
getBoundingClientRect()
scrollIntoViewIfNeeded()
什么是重绘
当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。
相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些。
重绘不一定导致重排,但重排一定会导致重绘。
触发重绘的操作
常见引起重排属性如下:
color
border-style
visibility
background
text-decoration
background-image
background-position
background-repeat
outline-color
outline
outline-style
border-radius
outline-width
box-shadow
background-size
什么是合成
合成指的是跳过重排和重绘阶段,只执行后续的合成操作。
这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率。
结语
浏览器输入 URL 发生了什么?
- 用户输入查询关键字。
- 如果是搜索内容,那么搜索引擎会合成带有关键字的 URL。
- 如果是符合规则的 URL,直接进入下一步。
- 浏览器进程通过 IPC 通信,把 URL 请求发送至网络进程。
- 网络进程接收到 URL 请求后检查本地缓存是否有该请求资源,如果有就返回给浏览器进程,没有就进入下一步。
- 网络进程向 Web 服务器发起请求过程如下:
- 4-1、DNS 解析以获取请求域名的 IP 地址,如果协议是 HTTPS 还需要建立 TLS 连接。
- 4-2、利用ip地址和服务器建立 TCP 连接。
- 4-3、构建请求头信息。
- 4-4、发送请求头信息。
- 4-5、服务器响应后,网络进程接收响应头和响应信息,并解析响应内容。
- 网络进程解析响应流程如下:
- 5-1、检查状态码,如果是 301/302,则需要重定向,自动从 Location 中读取地址,重新进行第 3 步,如果是 200,则继续处理请求。
- 5-2、200 响应处理:检查响应类型 Content-Type,如果是字节流类型,则将该请求提交给下载管理器,该导航流程结束,不再进行后续的渲染,如果是 html 则通知浏览器进程准备渲染进程准备进行渲染。
- 准备渲染进程:浏览器进程检查当前 url 是否和之前打开渲染进程的根域名相同,如果相同,则复用原来的进程,如果不同,则开启新的渲染进程。
- 更新界面状态
- 7-1、渲染进程准备好后,浏览器向渲染进程发起“提交文档”的消息,渲染进程接收到消息和网络进程建立传输数据的“管道”。
- 7-2、渲染进程接收完数据后,向浏览器发送“确认提交”。
- 7-3、浏览器进程接收到确认消息后更新浏览器界面状态:安全、地址栏url、前进后退的历史状态、更新 web 页面。
- 渲染阶段
- 8-1、构建 DOM 树。
- 8-2、样式计算。
- 8-3、布局阶段。
- 8-4、分层。
- 8-5、生成绘制指令。
- 8-6、分块。
- 8-7、光栅化。
- 8-8、合成显示。
这是学习《浏览器工作原理与实践》李兵老师课程的笔记。