From 8a35a5905cf0a5e906fac241be04a3bdb602f168 Mon Sep 17 00:00:00 2001
From: Jason Ren <40999116+jasonren0403@users.noreply.github.com>
Date: Mon, 30 Oct 2023 18:29:14 +0800
Subject: [PATCH] [zh-cn] Update 'how browsers work'
---
.../performance/how_browsers_work/index.md | 82 ++++++++++---------
1 file changed, 43 insertions(+), 39 deletions(-)
diff --git a/files/zh-cn/web/performance/how_browsers_work/index.md b/files/zh-cn/web/performance/how_browsers_work/index.md
index d7d0612b1c3fe0..b47fa5f71eec43 100644
--- a/files/zh-cn/web/performance/how_browsers_work/index.md
+++ b/files/zh-cn/web/performance/how_browsers_work/index.md
@@ -1,8 +1,12 @@
---
title: 渲染页面:浏览器的工作原理
slug: Web/Performance/How_browsers_work
+l10n:
+ sourceCommit: f32c38c1245815c7f520730f0cdef54960e5cee1
---
+{{QuickLinksWithSubPages("Web/Performance")}}
+
页面内容快速加载和流畅的交互是用户希望得到的 Web 体验,因此,开发者应力争实现这两个目标。
了解如何提升性能和感知性能,有助于了解浏览器的工作原理。
@@ -29,7 +33,7 @@ Web 性能优化的目标之一就是缩短导航完成所花费的时间,在
浏览器向**名称服务器**发起 DNS 查询请求,最终得到一个 IP 地址。第一次请求之后,这个 IP 地址可能会被缓存一段时间,这样可以通过从缓存里面检索 IP 地址而不是再通过名称服务器进行查询来加速后续的请求。
-通过主机名加载一个页面通常仅需要一次 DNS 查询。但是,对于页面指向的不同的主机名,则需要多次 DNS 查询。如果字体(fonts)、图像(images)、脚本(scripts)、广告(ads)和网站统计(metrics)都有不同的主机名,则需要对每一个主机名进行 DNS 查询。
+通过主机名加载一个页面通常仅需要一次 DNS 查询。但是,对于页面指向的不同的主机名,则需要多次 DNS 查询。如果字体(font)、图像(image)、脚本(script)、广告(ads)和网站统计(metric)都有不同的主机名,则需要对每一个主机名进行 DNS 查询。
![移动终端的请求先发送到基站,接着发送到运营商的中心计算机,然后再发送到互联网](latency.jpg)
@@ -43,7 +47,7 @@ TCP 的“三次握手”技术经常被称为“SYN-SYN-ACK”——更确切
### TLS 协商
-为了在 HTTPS 上建立安全连接,另一种握手是必须的。更确切的说是 {{glossary('TLS')}} 协商,它决定了什么密码将会被用来加密通信,验证服务器,在进行真实的数据传输之前建立安全连接。在发送真正的请求内容之前还需要三次往返服务器。
+对于通过 HTTPS 建立的安全连接,还需要另一次 "握手"。这种握手,或者说 {{glossary('TLS')}} 协商,决定使用哪种密码对通信进行加密,验证服务器,并在开始实际数据传输前建立安全连接。这就需要在实际发送内容请求之前,再往返服务器五次。
![DNS 查询、TCP 握手和 TLS 5 步握手(包括服务器和客户端之间的 clienthello、serverhello 以及证书、clientkey 和完成消息)。](ssl.jpg)
@@ -57,41 +61,41 @@ TCP 的“三次握手”技术经常被称为“SYN-SYN-ACK”——更确切
```html
-
+
- My simple page
-
+ 简单的页面
+
- My Page
- A paragraph with a link
+ 我的页面
+ 含有链接的段落。
-
+
```
-初始请求的响应包含所接收数据的第一个字节。{{glossary('Time to First Byte')}}(TTFB)是用户通过点击链接进行请求与收到第一个 HTML 数据包之间的时间。第一个内容分块通常是 14KB 的数据。
+初始请求的响应包含所接收数据的第一个字节。{{glossary('Time to First Byte','首字节时间(TTFB)')}}是用户通过点击链接进行请求与收到第一个 HTML 数据包之间的时间。第一个内容分块通常是 14KB 的数据。
-上面的例子中,这个请求肯定是小于 14KB 的,但是直到浏览器在解析阶段遇到链接时才会去请求链接的资源,下面有进行描述。
+上面的示例中,这个请求肯定是小于 14KB 的,但是直到浏览器在解析阶段遇到链接时才会去请求链接的资源,下面有进行描述。
-### TCP 慢启动 / 14KB 规则
+### 拥塞控制 / TCP 慢启动
-第一个响应数据包是 14KB 大小的。这是慢启动的一部分,慢启动是一种均衡网络连接速度的算法。慢启动逐渐增加发送数据的数量直到达到网络的最大带宽。
+TCP 数据包在传输过程中被分成若干段。由于 TCP 保证数据包的顺序,因此服务器在发送一定数量的数据包后,必须以 ACK 数据包的形式收到客户端的确认。
-在 {{glossary('TCP slow start', "TCP 慢启动")}} 中,在收到初始包之后,服务器会将下一个数据包的大小加倍到大约 28KB。后续的数据包依次是前一个包大小的二倍直到达到预定的阈值,或者遇到拥塞。
+如果服务器在每个网段后都等待 ACK,则会导致客户端频繁发出 ACK,即使在网络负荷较低的情况下也会增加传输时间。
-![TCP 慢启动](congestioncontrol.jpg)
+另一方面,一次性发送过多网段可能会导致这样的问题:在繁忙的网络中,客户端无法接收到网段,只能长时间不停地回应 ACK,服务器不得不不断重新发送网段。
-如果你听说过初始页面加载的 14KB 规则,TCP 慢启动就是初始响应为 14KB 的原因,也是为什么 web 性能优化需要将此初始 14KB 响应作为优化重点的原因。TCP 慢启动逐渐建立适合网络能力的传输速度,以避免拥塞。
+为了平衡传输段的数量,{{glossary('TCP slow start', 'TCP 慢启动')}} 算法用于逐渐增加传输数据量,直到确定最大网络带宽,并在网络负载较高时减少传输数据量。
-### 拥塞控制
+传输段的数量由拥塞窗口(CWND)的值控制,该值可初始化为 1、2、4 或 10 MSS(以太网协议中的 MSS 为 1500 字节)。该值是发送的字节数,客户端收到后必须发送 ACK。
-当服务器用 TCP 数据包来发送数据时,客户端通过返回确认帧来确认传输。由于硬件和网络条件,连接的容量是有限的。如果服务器太快地发送太多的包,它们可能会被丢弃。这意味着,将不会有确认帧的返回。服务器把它们当做确认帧丢失。拥塞控制算法使用这个发送包和确认帧流来确定发送速率。
+如果收到 ACK,那么 CWND 值将加倍,这样服务器下次就能发送更多的数据段。相反,如果没有收到 ACK,那么 CWND 值将减半。因此,这种机制在发送过多网段和过少网段之间取得了平衡。
## 解析
@@ -103,9 +107,9 @@ DOM 是浏览器标记的内部表示。DOM 也是被暴露的,可以通过 Ja
### 构建 DOM 树
-我们描述五个步骤在[关键渲染路径](/zh-CN/docs/Web/Performance/Critical_rendering_path)这篇文章中。
+我们在[关键渲染路径](/zh-CN/docs/Web/Performance/Critical_rendering_path)这篇文章中描述了五个步骤。
-第一步是处理 HTML 标记并构造 DOM 树。HTML 解析涉及到 [tokenization](/zh-CN/docs/Web/API/DOMTokenList) 和树的构造。HTML 标记包括开始和结束标记,以及属性名和值。如果文档格式良好,则解析它会简单而快速。解析器将标记化的输入解析到文档中,构建文档树。
+第一步是处理 HTML 标记并构造 DOM 树。HTML 解析涉及到[符号化](/zh-CN/docs/Web/API/DOMTokenList)和树的构造。HTML 标记包括开始和结束标记,以及属性名和值。如果文档格式良好,则解析它会简单而快速。解析器将标记化的输入解析到文档中,构建文档树。
DOM 树描述了文档的内容。[``](/zh-CN/docs/Web/HTML/Element/html) 元素是第一个标签也是文档树的根节点。树反映了不同标记之间的关系和层次结构。嵌套在其他标记中的标记是子节点。DOM 节点的数量越多,构建 DOM 树所需的时间就越长。
@@ -118,9 +122,9 @@ DOM 树描述了文档的内容。[``](/zh-CN/docs/Web/HTML/Element/html)
浏览器构建 DOM 树时,这个过程占用了主线程。当这种情况发生时,预加载扫描仪将解析可用的内容并请求高优先级资源,如 CSS、JavaScript 和 web 字体。多亏了预加载扫描器,我们不必等到解析器找到对外部资源的引用来请求它。它将在后台检索资源,以便在主 HTML 解析器到达请求的资源时,它们可能已经在运行,或者已经被下载。预加载扫描仪提供的优化减少了阻塞。
```html
-
+
-
+
```
@@ -136,45 +140,45 @@ DOM 树描述了文档的内容。[``](/zh-CN/docs/Web/HTML/Element/html)
CSSOM 树包括来自用户代理样式表的样式。浏览器从适用于节点的最通用规则开始,并通过应用更具体的规则递归地优化计算的样式。换句话说,它级联属性值。
-构建 CSSOM 非常非常快,并且在当前的开发工具中没有以独特的颜色显示。相反,开发人员工具中的“重新计算样式”显示解析 CSS、构建 CSSOM 树和递归计算计算样式所需的总时间。在 web 性能优化方面,它是可轻易实现的,因为创建 CSSOM 的总时间通常小于一次 DNS 查询所需的时间。
+构建 CSSOM 非常快,并且在当前的开发工具中没有以独特的颜色显示。相反,开发人员工具中的“重新计算样式”显示解析 CSS、构建 CSSOM 树和递归计算计算样式所需的总时间。在 web 性能优化方面,它是可轻易实现的,因为创建 CSSOM 的总时间通常小于一次 DNS 查询所需的时间。
### 其他过程
#### JavaScript 编译
-当 CSS 被解析并创建 CSSOM 时,其他资源,包括 JavaScript 文件正在下载(借助预加载扫描器)。JavaScript 被解释、编译、解析和执行。脚本被解析为抽象语法树。一些浏览器引擎使用[抽象语法树](https://zh.wikipedia.org/wiki/抽象语法树)并将其传递到解释器中,输出在主线程上执行的字节码。这就是所谓的 JavaScript 编译。
+在解析 CSS 和创建 CSSOM 的同时,包括 JavaScript 文件在内的其他资源也在下载(这要归功于预加载扫描器)。JavaScript 会被解析、编译和解释。脚本被解析为抽象语法树。有些浏览器引擎会将[抽象语法树](https://zh.wikipedia.org/wiki/抽象语法树)输入编译器,输出字节码。这就是所谓的 JavaScript 编译。大部分代码都是在主线程上解释的,但也有例外,例如在 [web worker](/zh-CN/docs/Web/API/Web_Workers_API) 中运行的代码。
-#### 构建辅助功能树
+#### 构建无障碍树
-浏览器还构建辅助设备用于分析和解释内容的辅助功能([accessibility](/zh-CN/docs/Learn/Accessibility))树。无障碍对象模型(AOM)类似于 DOM 的语义版本。当 DOM 更新时,浏览器会更新辅助功能树。辅助技术本身无法修改无障碍树。
+浏览器还构建辅助设备用于分析和解释内容的[无障碍](/zh-CN/docs/Learn/Accessibility)树。无障碍对象模型(AOM)类似于 DOM 的语义版本。当 DOM 更新时,浏览器会更新辅助功能树。辅助技术本身无法修改无障碍树。
-在构建 AOM 之前,屏幕阅读器([screen readers](/zh-CN/docs/Web/Accessibility/ARIA/ARIA_Screen_Reader_Implementors_Guide))无法访问内容。
+在构建 AOM 之前,[屏幕阅读器](/zh-CN/docs/Web/Accessibility/ARIA/ARIA_Screen_Reader_Implementors_Guide)无法访问内容。
## 渲染
-渲染步骤包括样式、布局、绘制,在某些情况下还包括合成。在解析步骤中创建的 CSSOM 树和 DOM 树组合成一个 Render 树,然后用于计算每个可见元素的布局,然后将其绘制到屏幕上。在某些情况下,可以将内容提升到它们自己的层并进行合成,通过在 GPU 而不是 CPU 上绘制屏幕的一部分来提高性能,从而释放主线程。
+渲染步骤包括样式、布局、绘制,在某些情况下还包括合成。在解析步骤中创建的 CSSOM 树和 DOM 树组合成一个渲染树,然后用于计算每个可见元素的布局,然后将其绘制到屏幕上。在某些情况下,可以将内容提升到它们自己的层并进行合成,通过在 GPU 而不是 CPU 上绘制屏幕的一部分来提高性能,从而释放主线程。
-### Style
+### 样式
-第三步是将 DOM 和 CSSOM 组合成一个 Render 树,计算样式树或渲染树从 DOM 树的根开始构建,遍历每个可见节点。
+关键呈现路径的第三步是将 DOM 和 CSSOM 组合成渲染树。计算样式树或渲染树的构建从 DOM 树的根开始,遍历每个可见节点。
-像 [``](/zh-CN/docs/Web/HTML/Element/head) 和它的子节点以及任何具有 `display: none` 样式的结点,例如 `script { display: none; }`(在 user agent stylesheets 可以看到这个样式)这些标签将不会显示,也就是它们不会出现在 Render 树上。具有 `visibility: hidden` 的节点会出现在 Render 树上,因为它们会占用空间。由于我们没有给出任何指令来覆盖用户代理的默认值,因此上面代码示例中的 `script` 节点将不会包含在 Render 树中。
+不会被显示的元素,如 [``](/zh-CN/docs/Web/HTML/Element/head) 元素及其子元素,以及任何带有 `display: none` 的节点,如用户代理样式表中的 `script { display: none; }`,都不会包含在渲染树中,因为它们不会出现在渲染输出中。应用了 `visibility: hidden` 的节点会包含在渲染树中,因为它们会占用空间。由于我们没有给出任何指令来覆盖用户代理默认值,因此上述代码示例中的 `script` 节点不会包含在渲染树中。
-每个可见节点都应用了其 CSSOM 规则。Render 树保存所有具有内容和计算样式的可见节点——将所有相关样式匹配到 DOM 树中的每个可见节点,并根据 [CSS 级联](/zh-CN/docs/Web/CSS/Cascade)确定每个节点的计算样式。
+每个可见节点都应用了 CSSOM 规则。渲染树包含所有可见节点的内容和计算样式,将所有相关样式与 DOM 树中的每个可见节点匹配起来,并根据 [CSS 级联](/zh-US/docs/Web/CSS/Cascade),确定每个节点的计算样式。
-### Layout
+### 布局
-第四步是在渲染树上运行布局以计算每个节点的几何体。布局是确定呈现树中所有节点的宽度、高度和位置,以及确定页面上每个对象的大小和位置的过程。回流是对页面的任何部分或整个文档的任何后续大小和位置的确定。
+第四步是在渲染树上运行布局以计算每个节点的几何体。*布局*是确定呈现树中所有节点的宽度、高度和位置,以及确定页面上每个对象的大小和位置的过程。回流是对页面的任何部分或整个文档的任何后续大小和位置的确定。
构建渲染树后,开始布局。渲染树标识显示哪些节点(即使不可见)及其计算样式,但不标识每个节点的尺寸或位置。为了确定每个对象的确切大小和位置,浏览器从渲染树的根开始遍历它。
-在网页上,大多数东西都是一个盒子。不同的设备和不同的桌面意味着无限数量的不同的视区大小。在此阶段,考虑到视区大小,浏览器将确定屏幕上所有不同框的尺寸。以视区的大小为基础,布局通常从 body 开始,用每个元素的框模型属性排列所有 body 的子孙元素的尺寸,为不知道其尺寸的替换元素(例如图像)提供占位符空间。
+在网页上,大多数东西都是一个盒子。不同的设备和不同的桌面意味着无限数量的不同的视区大小。在此阶段,考虑到视口大小,浏览器将确定屏幕上所有不同框的尺寸。以视口的大小为基础,布局通常从 body 开始,用每个元素的框模型属性排列所有 body 的子孙元素的尺寸,为不知道其尺寸的替换元素(例如图像)提供占位符空间。
-第一次确定节点的大小和位置称为布局。随后对节点大小和位置的重新计算称为回流。在我们的示例中,假设初始布局发生在返回图像之前。由于我们没有声明图像的大小,因此一旦知道图像大小,就会有回流。
+第一次确定节点的大小和位置称为布局。随后对节点大小和位置的重新计算称为回流。在我们的示例中,假设初始布局发生在返回图像之前。由于我们没有声明图像的尺寸,因此一旦知道图像的尺寸,就会出现回流。
### 绘制
-最后一步是将各个节点绘制到屏幕上,第一次出现的节点称为 [first meaningful paint](/zh-CN/docs/Glossary/first_meaningful_paint)。在绘制或光栅化阶段,浏览器将在布局阶段计算的每个框转换为屏幕上的实际像素。绘画包括将元素的每个可视部分绘制到屏幕上,包括文本、颜色、边框、阴影和替换的元素(如按钮和图像)。浏览器需要非常快地完成这项工作。
+最后一步是将各个节点绘制到屏幕上,第一次出现的节点称为 [first meaningful paint](/zh-CN/docs/Glossary/First_meaningful_paint)。在绘制或光栅化阶段,浏览器将在布局阶段计算的每个框转换为屏幕上的实际像素。绘画包括将元素的每个可视部分绘制到屏幕上,包括文本、颜色、边框、阴影和替换的元素(如按钮和图像)。浏览器需要非常快地完成这项工作。
为了确保平滑滚动和动画,占据主线程的所有内容,包括计算样式,以及回流和绘制,必须让浏览器在 16.67 毫秒内完成。在 2048x1536 分辨率的 iPad 上,有超过 314.5 万像素将被绘制到屏幕上。那是很多像素需要快速绘制。为了确保重绘的速度比初始绘制的速度更快,屏幕上的绘图通常被分解成数层。如果发生这种情况,则需要进行合成。
@@ -182,7 +186,7 @@ CSSOM 树包括来自用户代理样式表的样式。浏览器从适用于节
分层确实可以提高性能,但是它以内存管理为代价,因此不应作为 web 性能优化策略的一部分过度使用。
-### Compositing
+### 合成
当文档的各个部分以不同的层绘制,相互重叠时,必须进行合成,以确保它们以正确的顺序绘制到屏幕上,并正确显示内容。
@@ -190,9 +194,9 @@ CSSOM 树包括来自用户代理样式表的样式。浏览器从适用于节
## 交互
-一旦主线程绘制页面完成,你会认为我们已经“准备好了”,但事实并非如此。如果加载包含 JavaScript(并且延迟到 [`onload`](/zh-CN/docs/Web/API/GlobalEventHandlers/onload) 事件激发后执行),则主线程可能很忙,无法用于滚动、触摸和其他交互。
+一旦主线程绘制页面完成,你会认为我们已经“准备好了”,但事实并非如此。如果加载包含 JavaScript(并且延迟到 [`onload`](/zh-CN/docs/Web/API/GlobalEventHandlers/onload) 事件触发后执行),则主线程可能很忙,无法用于滚动、触摸和其他交互。
-{{glossary('Time to Interactive')}}(TTI)是测量从第一个请求导致 DNS 查询和 SSL 连接到页面可交互时所用的时间——可交互是 {{glossary('First Contentful Paint')}} 之后的时间点,页面在 50ms 内响应用户的交互。如果主线程正在解析、编译和执行 JavaScript,则它不可用,因此无法及时(小于 50ms)响应用户交互。
+{{glossary('Time to Interactive', '可交互时间(TTI)')}}是测量从第一个请求导致 DNS 查询和 SSL 连接到页面可交互时所用的时间——可交互是 {{glossary('First Contentful Paint')}} 之后的时间点,页面在 50ms 内响应用户的交互。如果主线程正在解析、编译和执行 JavaScript,则它不可用,因此无法及时(小于 50ms)响应用户交互。
在我们的示例中,可能图像加载很快,但 `anotherscript.js` 文件可能是 2MB,而且用户的网络连接很慢。在这种情况下,用户可以非常快地看到页面,但是在下载、解析和执行脚本之前,就无法滚动。这不是一个好的用户体验。避免占用主线程,如下面的网页测试示例所示: