这一道面试题非常经典,比较全面地考察了应聘者知识的掌握程度,其中涉及到了浏览器原理、网络协议、操作系统、Web 等一系列的知识。如果充分了解了这个过程到底发生了什么,就可以从更高的维度去做性能优化,去提高请求的响应速度,增加用户留存率。
简单流程解析
- 浏览器通过DNS解析出IP地址
- 客户端与浏览器建立TCP链接
- 客户端发出HTTP请求
- 服务端响应请求
- 浏览器根据响应数据渲染显示
详细流程
用户输入
- 用户输入关键字,浏览器判断是URL还是搜索内容
- 如果是搜索内容,则浏览器会使用默认的搜索引擎,合成带有搜索内容的URL
- 如果是URL,则根据规则,加上协议合成完整的URL
- 按下回车,浏览器进入加载状态
- 在流程继续之前,浏览器还有一个
beforeunload
事件可以执行 - 执行完
beforeunload
事件,流程继续,浏览器进入加载状态 - 页面还是之前的内容,要到等待提交文档阶段才会被替换新的内容
接下来进入页面资源请求过程,浏览器进程通过进程间通信(IPC)把URL请求发送至网络进程,在网络进程发起真正的URL请求流程
查找缓存
网络进程会查找本地缓存是否缓存了该资源
- 从缓存位置Service Worker、Memory Cache、Disk Cache、Push Cache依次查找
- Service Worker,浏览器独立线程,可以自由控制缓存那些文件、如何匹配缓存、如何读取缓存,并且是持续性的
- Memory Cache,内存中的缓存,读取数据比磁盘快,容量小,存储时间短
- Disk Cache,硬盘中的缓存,读取速度慢一点,容量大,存储时效长
- Push Cache是HTTP/2的内容,缓存时间很短暂,只在会话(Session)中存在,一旦会话结束就被释放
- 如果有缓存资源则直接返回资源给浏览器进程,请求结束
- 如果没有找到资源,则会进入网络请求流程
DNS解析
DNS即域名解析系统,网络请求过程是一个计算机向另一个计算机请求资源,是需要通过IP地址建立连接的。
- 如果用户输入的就是IP地址,则直接进入TCP连接阶段
- 如果用户输入的是域名,则需要进行DNS解析,得到服务器的IP地址再建立TCP连接
- 查找过程是浏览器缓存->操作系统缓存->Hosts文件->非权威域名服务器 -> 根域名服务器 -> 顶级域名服务器 -> 权威域名服务器
TCP连接
- 得到IP地址后进入TCP队列,单个域名是有TCP连接限制(最多6个)的,超出限制需要排队。
- 浏览器和服务端通过三次握手建立TCP连接
- 客户端向服务端发送连接请求报文
- 服务端收到连接请求报文段后,如果同意连接,则会发送一个应答
- 当客户端收到连接同意的应答后,要向服务端发送一个确认报文
- 如果请求协议是HTTPS,TCP连接后还要建立TLS连接(安全地交换对称密钥)
发出HTTP请求
连接建立后,浏览器端会构建请求行、请求头等信息,然后向服务器发送请求信息
- 请求行简要地描述了客户端想要如何操作服务器端的资源,由三部分构成:
- 请求方法:是一个动词,如
GET
/POST
,表示对资源的操作 - 请求目标:通常是一个URI,标记了请求方法要操作的资源
- 版本号:表示报文使用的HTTP协议版本
- 头部字段是
key-value
的形式,key
和value
之间用:
分隔,用CRLF换行,表示字段结束。
服务端响应请求
服务器接收到请求信息后,会根据请求信息生成响应数据(包括响应行、响应头和响应体等信息)返回
- 状态行代表服务器响应的状态,同样由三部分构成:
- 版本号:表示报文使用的HTTP协议版本
- 状态码:一个三位数,用代码的形式表示处理的结果,比如
200
是成功,500
是服务器错误 - 原因:作为数字状态码的补充,是更详细的解释文字,帮助人理解原因
网络进程解析响应信息
服务器返回信息给网络进程,网络进程接收后开始解析
- 解析响应头
- 如果发现返回状态码是
301
或302
,则说明服务器需要浏览器重定向到其他URL - 网络进程会从响应头的Location字段里面读取重定向的地址,然后再发起新的HTTP或HTTPS请求,重头开始
- 响应数据类型处理
- 通过Content-Type头字段区分数据类型
- Content-Type 是 HTTP 头中一个非常重要的字段, 它告诉浏览器服务器返回的响应体数据是什么类型,然后浏览器会根据 Content-Type 的值来决定如何显示响应体的内容
- 如果 Content-Type 字段的值被浏览器判断为下载类型,那么该请求会被提交给浏览器的下载管理器,同时该 URL 请求的导航流程就此结束
- 如果是 HTML类型,那么浏览器则会继续进行导航流程;由于 Chrome 的页面渲染是运行在渲染进程中的,所以接下来就需要准备渲染进程了。
准备渲染进程
- 默认情况下,Chrome 会为每个页面分配一个渲染进程
- 通常情况下,打开新的页面都会使用单独的渲染进程;
- 如果从 A 页面打开 B 页面,且 A 和 B 都属于同一站点(拥有相同的协议和根域名)的话,那么 B 页面复用 A 页面的渲染进程;如果是其他情况,浏览器进程则会为 B 创建一个新的渲染进程。
- 渲染进程准备好之后,还不能立即进入文档解析状态,因为此时的文档数据还在网络进程中,并没有提交给渲染进程,所以下一步就进入了提交文档阶段
提交文档
提交文档,就是指浏览器进程将网络进程接收到的 HTML 数据提交给渲染进程。
具体流程是:
- 首先当浏览器进程接收到网络进程的响应头数据之后,便向渲染进程发起“提交文档”的消息;
- 渲染进程接收到“提交文档”的消息后,会和网络进程建立传输数据的“管道”;
- 等文档数据传输完成之后,渲染进程会返回“确认提交”的消息给浏览器进程;
- 浏览器进程在收到“确认提交”的消息后,会更新浏览器界面状态,包括了安全状态、地址栏的 URL、前进后退的历史状态,并更新 Web 页面。
这也解释了为什么在浏览器的地址栏里面输入了一个地址后,之前的页面没有立马消失,而是要加载一会儿才会更新页面。
以上流程是浏览器的导航流程,涵盖了从用户发起请求到提交文档给渲染进程的中间所有阶段。接下来则是渲染流程了。
渲染流程的子阶段都会经历三个阶段:
- 开始每个子阶段都有其输入的内容;
- 然后每个子阶段有其处理过程;
- 最终每个子阶段会生成输出内容。
构建 DOM 树
浏览器无法直接理解和使用 HTML,所以渲染进程会将 HTML 转换为浏览器能够理解的结构——DOM 树
- 输入:一个简单的HTML文件
- 处理:HTML解析器解析,字节数据->字符串->标记(token)->Node->DOM树
- 输出:输出一个树状结构的DOM,可以通过 JavaScript 来查询或修改其内容
样式计算
样式计算的目的是为了计算出 DOM 节点中每个元素的具体样式,在计算过程中需要遵守 CSS 的继承和层叠两个规则。
- 输入:CSS 样式来源主要有三种
- 通过
link
引用的外部 CSS 文件 <style>
标记内的 CSS- 元素的
style
属性内嵌的 CSS
- 处理:
- 转换样式表中的属性值,使其标准化(所有值转换为渲染引擎容易理解的、标准化的计算值)
- 计算出 DOM 树中每个节点的具体样式
- 输出:浏览器能够理解的结构——styleSheets
布局
计算出 DOM 树中可见元素的几何位置,这个计算过程叫做布局。在布局阶段需要完成两个任务
- 创建布局树
- 在显示之前,要额外地构建一棵只包含可见元素布局树
- 遍历 DOM 树中的所有可见节点,并把这些节点加到布局树中
- 而不可见的节点会被布局树忽略掉,如属性包含
dispaly:none
的元素不会被包进布局树
- 布局计算:计算布局树节点的坐标位置
分层
页面中有很多复杂的效果,如一些复杂的 3D 变换、页面滚动,或者使用 z-indexing
做 z
轴排序等,为了更加方便地实现这些效果,渲染引擎需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree)。
- 特定节点生成专用图层,生成一棵图层树(层叠上下文、Clip,类似 PhotoShop 里的图层);
- 拥有层叠上下文属性(明确定位属性、透明属性、CSS 滤镜、
z-index
等)的元素会创建单独图层; - 没有图层的 DOM 节点属于父节点图层;
- 需要剪裁的地方也会创建图层。
图层绘制
- 输入:图层树
- 处理:
- 渲染引擎对图层树中每个图层进行绘制
- 拆分成绘制指令,生成绘制列表,提交到合成线程
- 输出:绘制列表
栅格化操作
绘制列表只是用来记录绘制顺序和绘制指令的列表,而实际上绘制操作是由渲染引擎中的合成线程来完成的。
- 根据视口(用户看到的区域),合成线程会将图层划分为图块(tile)
- 合成线程会按照视口附近的图块来优先生成位图
- 实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图
- 栅格化过程都会使用 GPU 来加速生成,使用 GPU 生成位图的过程叫快速栅格化,或者 GPU 栅格化,生成的位图被保存在 GPU 内存中
合成和显示
- 一旦所有图块都被栅格化,合成线程就会生成一个绘制图块的命令——“
DrawQuad
”,然后将该命令提交给浏览器进程 - 浏览器进程里面有一个叫
viz
的组件,用来接收合成线程发过来的DrawQuad
命令,然后将其页面内容绘制到内存中,最后再将内存显示在屏幕上。
这样到显示阶段,页面就加载显示完成了,这就是整个过程了
小结
以上就是我所理解的从输入URL到页面展示,中间发生的事情了,涉及了很多方面的知识;除了上面这些内容还可以延伸出很多内容,比如HTTP缓存策略、DNS解析出CDN(内容分发网络)的IP地址拿静态资源缓存、TCP三次握手四次挥手、HTTPS安全在哪里、服务端如何更快响应、安全防范知识、重绘和回流以及怎么减少、以及这一个请求流程下来如何做性能优化等。这样的一个体系的知识,如果能理解透彻,是绝对可以在工作中起到很大的作用的。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!