DOMContentLoaded 与加载事件:时机与自动化

DOMContentLoaded 与加载事件

Scrapeless Scraping 浏览器为需要精确文档和资源就绪信号的自动化工作流程提供托管的 Chromium 会话。

简而言之

  • DOMContentLoaded 意味着初始 HTML 被解析和延期的脚本已运行。 它不会等待每个图像、样式表背景资产或子资源。
  • 窗口加载事件在正常生命周期中稍后触发。 它等待文档及其急切加载的依赖资源完成。
  • 两个事件都不能证明一个应用已经准备好进行特定操作。 客户端渲染、异步数据、动画和延迟加载可以在之后继续。
  • 自动化应该等待最早的有意义条件。 选择器、应用状态或响应通常比全局页面事件更精确。
  • 晚期监听器必须检查 document.readyState。 异步加载的脚本可能在 DOMContentLoaded 已经触发后执行。

为什么生命周期范围很重要

在 DOMContentLoaded 和加载事件之间的选择会影响浏览器如何暴露状态、渲染内容或决定何时进行自动化操作是安全的。精确的定义可以防止团队将狭窄的信号视为普遍答案。这也使得测试失败更容易诊断,因为预期的浏览器行为与文档化的生命周期、API 或系统边界相关。

对于 Web 自动化,实际的问题总是比“页面是否准备好?”或“浏览器看起来是否真实?”要狭隘。下一步可能需要启用一个控件、一个框架完成导航、一个组件附加其内部树,或一个渲染表面保持一致。下面的部分将概念转变为可观察的检查,而不是依赖于民间传说。

简短回答

DOMContentLoaded 在浏览器解析初始 HTML 文档并执行解析算法要求的脚本时触发。窗口加载事件在文档及其急切加载的依赖资源完成加载后触发。在典型页面中,DOMContentLoaded 首先到达,而加载稍后到达。

MDN DOMContentLoaded 参考 解释该事件不会等待图像完成并确实会等待延期的脚本。这使它成为需要 DOM 树但不依赖于每个视觉资产的代码的有用信号。当脚本等待样式表时,样式表仍然可以间接影响时机。

区别在于生命周期范围,而不是页面质量。解析后的 DOM 仍然可以包含占位符。已加载的页面仍然可以打开套接字、获取更多数据或渲染延迟组件。正确的事件取决于下一个操作所需的内容。

什么发生在 DOMContentLoaded 之前

HTML 解析器读取标记并构建 DOM。一个经典脚本没有 defer 或 async 可能会在获取和执行时暂停解析。延期脚本在不阻塞解析的情况下获取,并在解析后执行,在 DOMContentLoaded 之前。模块脚本遵循相关的延期行为。异步脚本在可用时执行,并不建立相同的顺序保证。

当 DOMContentLoaded 被调度时,document.readyState 已移动到交互状态。初始标记中的元素可供查询,并且解析生命周期所需的延期工作已运行。代码可以附加事件处理程序、初始化组件或检查文档,而无需等待不影响这些任务的大图像。

动态加载的脚本可能在该事件之后执行。健壮的初始化代码检查 document.readyState:如果文档仍在加载,则注册 DOMContentLoaded 监听器;否则立即运行。这防止了将监听器附加到已经发生的事件而导致的潜在失败。

加载事件添加了什么

MDN 窗口加载参考 将加载定义为整个页面加载的时刻,包括参与急切加载的依赖资源,如样式表、脚本、图像和嵌入框。该事件在文档生命周期中以窗口的形式触发。

当代码确实依赖于内在图像尺寸、完成的 iframe 加载或应包括急切资源的可视捕获时,加载是有用的。对于仅需要表单或导航控件的交互来说,它过于保守。等待每个资产可能会增加延迟,而不提高可靠性。

延迟加载使“整个页面”的短语复杂化。标记为延迟加载的图像和 iframe 可能在初始加载事件之前未被获取。应用程序也可以根据计时器、用户交互、观察者或组件效果稍后启动网络请求。加载结束了一个定义的生命周期阶段;它并没有声明应用程序永久完成。

自动化的时机比较

选择 DOMContentLoaded 可以减少在图像繁重、分析或长时间资源活动的页面上的等待时间。在事件之后,自动化可以等待目标元素或应用状态的变化。选择加载可以简化需要急切视觉资产的工作流程,但它可能仍然会错过异步应用数据,并可能会等待与该任务无关的资源。

最佳自动化等待是证明下一步安全的最早信号。要点击搜索框,请等待该框可见并启用。要提取结果列表,请等待列表容器和已完成的应用状态。要捕获图像库,请等待相关图像报告完成并具有非零的内在尺寸。

全球事件是有用的导航里程碑,而不是普遍的准备检查。将合乎逻辑的导航事件与有针对性的断言结合起来。这使得失败具有诊断意义:缺失的选择器表示预期的用户界面从未出现,而通用的导航超时仅表示未满足一个广泛的条件。

单页面应用程序、水合和数据获取

单页面应用程序可以接收一个小的HTML外壳,达到DOMContentLoaded,然后再获取路由数据并给组件水合。如果它的重要获取从JavaScript开始在生命周期资源集建立后,加载事件也可能在应用程序的最终内容出现之前触发。

水合为服务器渲染的标记添加事件监听器和状态。一个元素可以在它正确响应交互之前存在。测试应该等待一个应用程序可见的准备标记、一个启用的控件或一个表示完成水合的稳定状态。单靠出现可能不足。

流式和增量渲染使最终页面的概念变得更加无用。内容可以分块抵达,用户可见区域可以在不同时间变得可用。将每个操作视为状态转换:导航创建了文档,一个组件变得可交互,一个请求填充了数据,一个控件变得可操作。

HTML标准如何框架准备状态

HTML文档准备算法 定义加载、交互和完成状态,并指定何时排队准备事件。DOMContentLoaded 与解析工作后的交互阶段相关,而 load 跟随文档的完成处理。

理解 readyState 有助于调试事件顺序问题。加载意味着解析正在进行中。交互意味着解析已完成,但子资源仍在加载。完成意味着文档和相关子资源已经完成加载生命周期。这些状态是可观察的快照,代码仍然必须测试其自己的应用前提。

对于性能测量,浏览器导航时间会暴露单独的 DOMContentLoaded 和加载时间戳。这个差距可以揭示资源成本,但任一指标单独都无法描述用户何时可以完成任务。将生命周期指标与任务导向的措施配对,例如主要内容或交互控件何时可用。

选择下一个准备信号

从最小的条件或配置开始,证明任务可以继续。保持与标准兼容的浏览器行为,仅在工作流需要时添加个人资料控件。记录浏览器构建和相关状态,以便后续差异可以得到解释。可重复的观察比“页面”、“框架”、“显示”或“指纹”只是“完成”或“安全”的宽泛声明更有用。

  • 定义下一个动作。 确切说明脚本或用户在等待或配置步骤后需要执行的操作。
  • 选择一个可观察的信号。 优先选择直接支持该动作的浏览器属性、生命周期状态、元素条件或渲染结果。
  • 保持相关值一致。 浏览器、操作系统、屏幕、区域设置、图形和会话设置应描述一个合理的环境。
  • 验证正常应用程序行为。 隐私或自动化干预不应默默破坏其更改的 API 或组件。
  • 捕获诊断证据。 当检查失败时,保存相关的 URL、状态、控制台消息和配置名称。

结论

DOMContentLoaded标记一个已解析、脚本准备的文档,而load标记初始急切资源生命周期的完成。DOMContentLoaded 通常是更好的早期导航里程碑;当下一步骤依赖于急切资产时,load 是有用的。可靠的自动化会等待特定元素、数据条件或应用状态,而不是将任一全局事件视为完全准备的证据。

无痕抓取浏览器文档 解释了如何配置托管浏览器会话,而 抓取浏览器产品概述 描述了浏览器自动化表面。这些资源提供了在授权工作流中应用该概念的产品上下文。

准备使用更精确的页面等待吗?

将浏览器渲染、会话配置和自动化基础设施迁移到托管的 Chromium 环境中。

今天注册并获取 $5 的免费信用不需要信用卡.

领取您的 $5 信用 →

常见问题

哪个事件先触发,DOMContentLoaded 还是 load?

由于它不等待加载事件包含的所有急切图像和相关资源,因此 DOMContentLoaded 通常先触发。

DOMContentLoaded 是否等待延迟脚本?

是的。延迟脚本和模块脚本在解析后并在 DOMContentLoaded 之前执行,受文档的脚本处理规则的限制。

load 是否等待懒加载的图像?

不一定。原生懒加载延迟的资源可能在初始窗口加载事件之后加载。

浏览器自动化应该使用哪个事件?

使用与页面兼容的最早生命周期事件,然后等待所需的特定元素或应用状态以进行下一个操作。

参考文献