(翻译)Web 浏览器如何一步步工作4 — 加载阶段优化

了解浏览器如何工作有什么意义?我们可以满怀信心地提高性能。 使用浏览器时,通常我们会打开一个 URL,与页面交互,并在获得所需内容后关闭选项卡。 用户和浏览器之间的整个交互过程分为三个阶段:

  1. 加载阶段 ( Loading stage ) --- 从我们输入 URL 时开始。
  2. 交互阶段 ( Interaction stage ) --- 当我们可以浏览、点击页面并与页面交互时就开始了。
  3. 关闭阶段 ( Closing stage ) - 当我们单击选项卡上的关闭按钮时开始。

Web前端优化主要集中在加载和交互阶段。 从导航到渲染阶段,最关键的优化点是DOM构建阶段。许多因素可能会阻碍 HTML 解析并延长整个渲染阶段。当这种情况发生时,我们作为用户,不得不盯着白色的屏幕一段时间。

DOM 构造阻塞

在上一篇文章中,我们专注于渲染阶段并跳过了 HTML 解析的一些细节。 HTML 文档不仅仅包含 HTML,还包括 CSS 样式和 JavaScript 文件。两者都可能阻止 DOM 构建并降低 Web 性能。

JavaScript 如何阻止 DOM 构建?

让我们从一个简单的例子开始,一个内联 JavaScript。

在示例中,脚本替换了元素的内部文本。它修改 DOM 树。

HTML 解析器负责"翻译"HTML 文档。当看到 JavaScript 脚本时,HTML 会停止解析 DOM 并立即执行它。执行完成后,HTML 解析器继续解析 HTML 文档的其余部分。 如果它是链接到 script 标签的 JavaScript 文件怎么办?

当再次看到链接的脚本文件时,HTML 解析器会停止 DOM 树构建。同时,渲染器进程与网络进程通信,请求从服务器下载 JavaScript 文件。当网络进程传递数据时,渲染器进程在继续解析 HTML 文件之前执行脚本。 除了浏览器执行 JavaScript 的时间之外,下载过程还增加了构建 DOM 树的时间。

CSS 如何阻止 DOM 构建?

CSS 不会阻碍 DOM 构建。与 JavaScript 结合时确实如此。

在这种情况下,HTML 中引用了 CSS 样式文件,JavaScript 修改了"styles.css"文件中的样式。 在执行 JavaScript 来修改样式之前,渲染器进程需要准备好计算样式。因此,HTML 解析器无法继续,直到 CSS 文件解析完成,并且 JavaScript 文件执行完成。

在开发网站的时候,我们的HTML文档中难免会有链接文件。 为了加速该过程,预加载扫描器在构建 DOM 树的同时快速扫描文档数据。如果预加载扫描程序发现任何链接文件(例如 CSS 和 JavaScript 文件),它会创建与网络进程的 IPC 连接并向服务器请求数据。 渲染器进程何时恢复 DOM 结构?这取决于下载时间最长的文件。 假设需要下载两个文件。一个文件需要 1 秒,另一个文件需要 3 秒。总共是3秒。

加载阶段的优化是为了减少下载时间

在构建 DOM 树时,最耗时的部分是下载链接文件和执行 JavaScript。

关键指标------往返延迟时间 ( round-trip delay time, RTD )

当谈到优化时,我们需要一个关键指标来衡量它,这样我们就知道解决方案是否有效。 往返延迟时间 (RTD) 或往返时间 (RTT) 是电信领域的通用术语,测量发送和接收信号所需的时间长度。 在我们的上下文中,时间测量在网络进程向服务器发送请求时开始,在收到服务器的完整确认时结束。 RTD 是完成此过程所需的总时间长度。 由于 TCP 的特性,数据是以块的形式发送的。以一个 CSS 文件为例,大小为0.1M。通过 HTTP 发送的每个分块数据包的大小通常约为 14KB。一个0.1M的文件被分成8个包。我们可以说 CSS 文件需要 8 RTD 才能完成。 下载两个文件怎么样?一个 CSS 文件为 9KB,因此下载需要 1 RTD。另一个 JavaScript 文件大小为 15KB,需要 2 RTD 才能完成下载。由于下载是并行进行的,因此总时间为 2 RTD。 这里的计算并不完全准确,因为我们忽略了 TCP 连接时间和服务器响应时间,但你明白了。 考虑到 RTD,现在我们可以讨论优化:

  • 减少关键资源的数量
  • 最小化关键资源的大小

减少关键资源的数量

关键资源有哪些?加载页面时需要任何 CSS 和 JavaScript 文件。没有它们,您的网站就会崩溃。 为了减少链接文件,我们可以将必要的 CSS 和 JavaScript 数据直接移动到 HTML 文件中,以避免下载过程。 如果某些链接的 JavaScript 文件不会改变 DOM 树和样式,请用"defer"和/或"async"标记它们,这样它们就不会阻止 DOM 构造。 当 DOM 准备好但在"DOMContentLoaded"事件之前执行延迟脚本。异步脚本独立于其他脚本和事件。一旦可用,它就会立即运行。 有些人认为,它有助于根据媒体查询将大型 CSS 文件分成较小的文件。这并不完全正确。即使查询返回 false,仍会下载带有附加到其 标记的媒体查询的样式表。只是内容不适用样式。因此,它不会减少下载请求。

减少关键资源的规模

文件大小越小意味着 RTD 越少。我们可以通过压缩CSS和JavaScript文件来实现。此外,大多数压缩工具都会删除数据中的注释,这有助于减小文件大小。

参考

相关推荐
listhi5201 小时前
利用React Hooks简化状态管理
前端·javascript·react.js
一点一木1 小时前
🚀 2025 年 10 月 GitHub 十大热门项目排行榜 🔥
前端·人工智能·github
华仔啊2 小时前
这个Vue3旋转菜单组件让项目颜值提升200%!支持多种主题,拿来即用
前端·javascript·css
非凡ghost2 小时前
Adobe Lightroom安卓版(手机调色软件)绿色版
前端·windows·adobe·智能手机·软件需求
BestAns3 小时前
Postman 平替?这款轻量接口测试工具,本地运行 + 批量回归超实用!
前端
专注前端30年3 小时前
Webpack进阶玩法全解析(性能优化+高级配置)
前端·webpack·性能优化
烛阴3 小时前
Lua世界的基石:变量、作用域与七大数据类型
前端·lua
张拭心3 小时前
“不卷 AI、不碰币、下班不收消息”——Android 知名技术大牛 Jake Wharton 的求职价值观
android·前端·aigc
SoaringHeart3 小时前
Flutter疑难解决:单独让某个页面的电池栏标签颜色改变
前端·flutter
Yeats_Liao3 小时前
Go Web 编程快速入门 13 - 部署与运维:Docker容器化、Kubernetes编排与CI/CD
运维·前端·后端·golang