从输入URL到回车发生了什么

这是一个经典的面试题:html

了解这个问题先看下chrome进程架构图git



从图中能够看出Chrome浏览器包括:1个浏览器主进程,1个GPU进程,一个网络进程,多个渲染进程,多个插件进程(能够没有)github


接下来看下从输入URL到页面展现完成示意图:web


1.用户输入回车

当输入的协议或主机名不合法时,浏览器会将地址栏中输入的文字传给默认的搜索引擎,来合成新的带搜索关键字的URL面试

若是判断输入内容符合 URL 规则,好比输入的是 www.baidu.com,那么地址栏会根据规则,把这段内容加上协议,合成为完整的 URL www.baidu.comchrome

接着就进入了加载阶段浏览器

当浏览器刚开始加载一个地址以后,标签页上的图标便进入了加载状态。但此时图中页面显示的依然是以前的页面内容,由于须要等待提交文档阶段,页面内容才会被替换。
缓存

2.URL请求过程

接下来,进入页面资源请求过程。浏览器进程会经过进程间通讯(IPC)把 URL 请求发送至网络进程,网络进程接收到 URL 请求后,发起 URL 请求流程
安全

网络进程会查找本地缓存是否缓存了该资源。若是有缓存资源,那么直接返回资源给浏览器进程;若是在缓存中没有查找到资源,那么直接进入网络请求流程。这请求前的第一步是要进行 DNS 解析,获取请求域名的服务器 IP 地址
服务器

接下来就是利用 IP 地址和服务器创建 TCP 链接。



链接创建以后,浏览器端会构建请求行、请求头等信息,并把和该域名相关的 Cookie 等数据附加到请求头中,而后向服务器发送构建的请求信息。下面的图打印出服务器收到的信息:


服务器接收到请求信息后,会根据请求信息生成响应数据(包括响应行、响应头和响应体等信息),并发给网络进程。等网络进程接收了响应行和响应头以后,就开始解析响应头的内容了。

收到服务器返回信息

服务器返回的响应头的状态码是 200,这是告诉浏览器一切正常,能够继续往下处理该请求了。

而后浏览器会根据 Content-Type 的值来决定如何显示响应体的内容。

Content-Type:  text/html;charset=utf-8

不一样 Content-Type 的后续处理流程也大相径庭。若是 Content-Type 字段的值被浏览器判断为下载类型,那么该请求会被提交给浏览器的下载管理器,同时该 URL 请求的导航流程就此结束

3. 准备渲染进程

Chrome 会为每一个页面分配一个渲染进程,也就是说,每打开一个新页面就会配套建立一个新的渲染进程(打开同一站点的共用一个渲染进程)

4. 提交文档

“提交文档”的消息是由浏览器进程发出的,渲染进程接收到“提交文档”的消息后,会和网络进程创建传输数据的“管道"

等文档数据传输完成以后,渲染进程会返回“确认提交”的消息给浏览器进程。

浏览器进程在收到“确认提交”的消息后,会更新浏览器界面状态,包括了安全状态、地址栏的 URL、前进后退的历史状态,并更新 Web 页面。

5.渲染阶段

先理解什么是DOM

 从网络传给渲染引擎的 HTML 文件字节流是没法直接被渲染引擎理解的,因此要将其转化为渲染引擎可以理解的内部结构,这个结构就是 DOM。DOM 提供了对 HTML 文档结构化的表述。

  • 从页面的视角来看,DOM 是生成页面的基础数据结构。
  • 从 JavaScript 脚本视角来看,DOM 提供给 JavaScript 脚本操做的接口,经过这套接口,JavaScript 能够对 DOM 结构进行访问,从而改变文档的结构、样式和内容。

渲染进程接收到“提交文档”的消息后,会和网络进程创建传输数据的“管道"

在渲染引擎内部,有一个叫HTML 解析器(HTMLParser)的模块,它的职责就是负责将 HTML 字节流转换为 DOM 结构。

网络进程接收到响应头以后,会根据响应头中的 content-type 字段来判断文件的类型,好比 content-type 的值是“text/html”,那么浏览器就会判断这是一个 HTML 类型的文件,而后为该请求选择或者建立一个渲染进程。渲染进程准备好以后,网络进程和渲染进程之间会创建一个共享数据的管道  网络进程接收到数据后就往这个管道里面放,而渲染进程则从管道的另一端不断地读取数据,并同时将读取的数据“喂”给 HTML 解析器。你能够把这个管道想象成一个“水管”,网络进程接收到的字节流像水同样倒进这个“水管”,而“水管”的另一端是渲染进程的 HTML 解析器,它会动态接收字节流,并将其解析为 DOM。


样式计算(Recalculate Style)

样式计算的目的是为了计算出 DOM 节点中每一个元素的具体样式,这个阶段大致可分为三步来完成。

CSS 样式来源主要有三种:

  • 经过 link 引用的外部 CSS 文件
  • <style>标记内的 CSS
  • 元素的 style 属性内嵌的 CSS

和 HTML 文件同样,浏览器也是没法直接理解这些纯文本的 CSS 样式,因此当渲染引擎接收到 CSS 文本时,会执行一个转换操做,将 CSS 文本转换为浏览器能够理解的结构——styleSheets

为了加深理解,你能够在 Chrome 控制台中查看其结构,只须要在控制台中输入 document.styleSheets,而后就看结构

3. 计算出 DOM 树中每一个节点的具体样式



布局阶段

你可能注意到了 DOM 树还含有不少不可见的元素,好比 head 标签,还有使用了 display:none 属性的元素。因此

在显示以前,咱们还要额外地构建一棵只包含可见元素布局树

分层


由于页面中有不少复杂的效果,如一些复杂的 3D 变换、页面滚动,或者使用 z-indexing 作 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还须要为特定的节点生成专用的图层,并生成一棵对应的图层树

要想直观地理解什么是图层,你能够打开 Chrome 的“开发者工具”,选择“Layers”标签,就能够可视化页面的分层状况,以下图所示:





图层绘制

渲染引擎实现图层的绘制会把一个图层的绘制拆分红不少小的绘制指令而后再把这些指令按照顺序组成一个待绘制列表,提交给合成线程

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

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

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

问题:


  • 为何必定要经过浏览器内核请求资源,再将数据转发给渲染进程而不是直接去请求资源
  • 为何渲染进程只负责生成图片,生成图片还有经过IPC通知浏览器内核模块,交由内核去展现图片

基于安全考虑:下载一个恶意程序,不去执行他,恶意程序是不会生效的,解析执行这些内容就要当心了,因此渲染进程和操做系统进行了隔离便是安全沙箱,因此渲染进程须要访问系统资源都是经过浏览器内核实现,经过IPC通讯获取结果!


浏览器的加载过程

浏览器调试使用

what-happens-when-zh_CN

相关文章
相关标签/搜索