浏览器从输入网址到显示页面的全过程:以 Chrome 为例

212 阅读9分钟

上一章我们以图书馆为例讲述了缓存的内容,本章我们就以餐厅牛排为例讲述浏览器渲染的内容。

一、从输入网址到页面展示

想象一下,你去一家餐厅吃饭。你告诉服务员你想吃什么(输入网址),服务员去厨房下单(DNS 解析),厨师开始准备食物(服务器处理请求),最后服务员把食物端到你面前(页面展示)。浏览器的工作过程也差不多。下面,我们详细看看这个过程。

1. 输入网址

你打开浏览器,在地址栏输入一个网址,比如 https://www.example.com,然后按下回车键。这就像是你告诉服务员你想吃一份牛排。浏览器会首先解析这个网址,提取出协议(https)、域名(www.example.com)和路径(/)等信息。

2. 找到网址对应的地址

浏览器首先要找到这个网址对应的服务器地址,这就像是服务员要找到厨房的位置。这个过程叫做 DNS 解析,它会把网址转换成一个 IP 地址,这样浏览器就知道去哪里找服务器了。DNS 解析的过程可能涉及本地缓存、系统 DNS 缓存、ISP 的 DNS 服务器或公共 DNS 服务器(如 Google 的 8.8.8.8)。这个过程通常在几毫秒到几秒内完成。

3. 建立连接

找到服务器地址后,浏览器会尝试和服务器建立连接,这就像是服务员和厨师打招呼,准备下单。这个过程叫做 建立 TCP 连接。建立 TCP 连接的过程包括三次握手:

  1. 浏览器发送一个 SYN(同步)包到服务器。
  2. 服务器回应一个 SYN-ACK(同步-确认)包。
  3. 浏览器发送一个 ACK(确认)包,完成连接建立。

4. 发送请求

连接建立后,浏览器会向服务器发送一个请求,说:“嘿,我要看看你的首页。”这就像是服务员把你的订单告诉厨师。HTTP 请求包括请求行(如 GET / HTTP/1.1)、请求头(如 Host: www.example.com)和请求体(如果有的话)。

5. 服务器响应

服务器收到请求后,会处理这个请求,然后把首页的内容(HTML 文件)发回给浏览器。这就像是厨师准备好牛排,让服务员端给你。服务器的响应包括状态码(如 200 OK)、响应头(如 Content-Type: text/html)和响应体(HTML 页面的内容)。

6. 下载 HTML 文件

浏览器收到服务器发来的 HTML 文件后,会把它保存下来,方便下次访问时更快加载。这就像是你把牛排放在盘子里,准备享用。浏览器会将 HTML 文件的内容存储到本地缓存中,以便后续的访问可以更快地加载。

7. 解析 HTML 文件

浏览器开始解析 HTML 文件,就像你开始吃牛排,但要先看看牛排的样子。浏览器会根据 HTML 文件的内容构建一个树状结构,叫做 DOM 树。DOM 树是一个层次化的节点树,表示 HTML 文档的结构。浏览器会将 HTML 标签解析为 DOM 节点,并按照文档的结构构建出 DOM 树。

8. 解析 CSS 文件

HTML 文件中可能还引用了 CSS 文件,这些文件告诉浏览器页面的样式。浏览器会解析这些 CSS 文件,构建一个 CSSOM 树,这就像是你看看牛排的调料和装饰。CSSOM 树是一个表示 CSS 规则的结构,它定义了页面中各个元素的样式。

9. 构建渲染树

有了 DOM 树和 CSSOM 树,浏览器就可以构建一个 渲染树 了。这个渲染树告诉浏览器页面的每个部分应该长什么样,这就像是你想象牛排在盘子里的样子。浏览器会结合 DOM 树和 CSSOM 树,构建渲染树。渲染树是一个包含 DOM 节点和 CSS 样式的树结构,用于表示页面的可视化部分。

10. 布局和绘制

浏览器根据渲染树计算每个元素的位置和大小,然后把它们绘制到屏幕上。这就像是你把牛排放在盘子里,摆好位置,然后开始吃。布局(Layout)和绘制(Painting)是两个关键步骤:

  • 布局:计算每个元素在页面上的位置和大小。
  • 绘制:将计算好的元素绘制到屏幕上,形成用户看到的页面。

11. 加载和执行 JavaScript

HTML 文件中可能还引用了 JavaScript 文件,这些文件可以让页面动起来。浏览器会下载并执行这些 JavaScript 文件,这就像是你在吃牛排的时候,突然有人在旁边表演魔术。JavaScript 的执行可能会阻塞页面的渲染,因此浏览器会尽量优化 JavaScript 的加载和执行过程。Chrome 使用 V8 引擎来执行 JavaScript,V8 引擎是单线程的,因此 JavaScript 的执行会阻塞渲染线程。如果 JavaScript 执行时间过长,就会造成页面渲染阻塞。

12. 页面加载完成

当所有的东西都加载和处理好了,浏览器会告诉你页面加载完成了。这就像是你吃完牛排,服务员告诉你:“先生,您的牛排已经全部上齐了。”浏览器会触发 DOMContentLoaded 事件,表示页面的主要内容已经加载完成。随后,浏览器会继续加载和执行页面中的异步资源,如 AJAX 请求等。

二、Chrome 的多进程、多线程架构

Chrome 浏览器就像是一个餐厅,里面有不同的员工(进程)和不同的任务(线程)。每个员工都有自己的职责,他们一起工作,让你的用餐(上网)体验更顺畅。

1. 浏览器的主要进程

Chrome 有几种主要的进程,就像餐厅里的不同员工:

1.1 浏览器主进程(Browser Process)

这个进程就像是餐厅的经理,负责整个餐厅的运营。它管理浏览器的界面(菜单、地址栏等),创建和管理其他进程,还和操作系统(房东)沟通,确保餐厅能正常营业。浏览器主进程的主要职责包括:

  • 管理浏览器的界面,如地址栏、标签页、菜单等。
  • 处理用户的导航请求,如打开新标签页、前进、后退等。
  • 创建和管理渲染进程、插件进程、下载进程等子进程。
  • 管理进程间的通信,确保各个进程能够协同工作。
  • 与操作系统和硬件进行交互,如处理文件下载、硬件加速等。

1.2 渲染进程(Renderer Process)

每个标签页都有一个渲染进程,就像每个顾客都有一个服务员。渲染进程负责把网页的内容(HTML、CSS、JavaScript)变成你看到的样子。它里面有多个线程,就像服务员有很多任务要做:

  • 渲染线程:负责把 HTML 和 CSS 变成页面的样子。它会构建 DOM 树、CSSOM 树、渲染树,计算页面的布局和样式,并进行绘制。
  • JS 引擎线程:负责执行 JavaScript 脚本,让页面动起来。Chrome 使用 V8 引擎来执行 JavaScript,V8 引擎是单线程的,因此 JavaScript 的执行会阻塞渲染线程。如果 JavaScript 执行时间过长,就会造成页面渲染阻塞。
  • GUI 线程:负责绘制页面的图形界面,如按钮、输入框等。GUI 线程与 JS 引擎线程是互斥的,如果 JS 引擎线程长时间占用 CPU,就会导致 GUI 线程无法及时响应,从而造成页面卡顿。
  • Event Loop 线程:负责处理页面的事件,如点击按钮、键盘输入等。Event Loop 线程会不断检查事件队列,将事件分发给相应的处理程序。如果事件队列中的任务过多,或者某个任务执行时间过长,就会导致页面响应变慢。

1.3 GPU 进程(GPU Process)

这个进程就像是餐厅里的厨师助手,专门负责图形相关的任务,比如动画和 3D 效果。它让页面看起来更漂亮,滚动更流畅。GPU 进程在 Chrome 中是唯一的,所有标签页共享同一个 GPU 进程。通过 GPU 加速,Chrome 能够实现更流畅的页面滚动、动画效果和 3D 变换。

1.4 插件进程(Plugin Process)

这个进程就像是餐厅里的特色厨师,负责处理一些特殊的插件,比如 Flash。它确保这些插件能正常工作,不会影响其他部分。插件进程的主要职责包括:

  • 加载和运行插件,提供插件的功能支持。
  • 管理插件的生命周期,确保插件的稳定运行。
  • 与渲染进程进行通信,协调插件与页面的交互。

1.5 下载进程(Download Process)

这个进程就像是餐厅里的外卖员,负责处理文件下载。它确保文件能正确地保存到你的电脑上。下载进程的主要职责包括:

  • 管理文件的下载,确保文件能够正确地保存到本地。
  • 提供下载进度的反馈,让用户了解下载状态。
  • 处理下载过程中的错误和异常情况。

2. 进程间的通信

这些进程之间需要互相沟通,就像餐厅里的员工需要互相配合。Chrome 使用一种叫做 IPC(进程间通信) 的机制,让这些进程可以发送和接收消息。浏览器主进程就像是餐厅的经理,负责协调其他进程的工作。IPC 机制允许进程之间发送和接收消息,实现数据的共享和任务的协调。

3. 分配资源的最小单元

在 Chrome 里,每个进程都有自己独立的资源,就像每个员工都有自己的工具和材料。这样,如果一个进程出问题了,不会影响其他进程。比如,一个标签页崩溃了,不会导致整个浏览器崩溃。这种设计提高了浏览器的稳定性和安全性。

三、总结

从输入网址到页面展示,浏览器要做很多工作,包括找到服务器、下载文件、解析文件、构建页面等。Chrome 通过多进程、多线程架构,把这些任务分配给不同的进程和线程,就像餐厅里的员工分工合作,让你的上网体验更顺畅、更安全。

希望这篇文章能帮助你更好地理解浏览器的工作原理。如果你有任何问题,欢迎在评论区留言讨论!


希望这个扩展后的版本能更好地帮助你理解浏览器的工作过程。如果有任何问题或需要进一步解释的地方,请随时告诉我。