JS中【加载事件线】带你进行由浅入深的解读

JavaScript 中的加载时间线详解

JavaScript 在网页的加载过程中扮演着关键角色,它的加载、解析、执行方式直接影响网页的性能和用户体验。要全面理解这一过程,我们需要深入探讨加载时间线中的每个步骤,以及各种技术对网页加载的影响。

1. HTML 文档解析(HTML Parsing)
  • 初始请求:当浏览器收到一个网页的 URL 请求时,它首先会发送一个 HTTP 请求以获取 HTML 文档。
  • 流式解析(Streaming Parsing):浏览器在接收到 HTML 文档的第一个字节时,就会开始逐行解析。这个过程是流式的,意味着解析和加载可以并行进行。
  • 遇到外部资源:在解析 HTML 的过程中,浏览器会遇到各种外部资源(如 CSS、JavaScript、图片等)。当遇到这些资源时,浏览器会立即发起请求来获取它们,但如何处理这些资源(尤其是 CSS 和 JavaScript)会对解析的继续进行产生影响。
2. CSS 阻塞渲染(CSS Blocking Rendering)
  • 遇到 <link> 标签:当浏览器解析到引用外部 CSS 文件的 <link> 标签或内嵌的 <style> 标签时,它会暂停 HTML 的进一步解析和渲染。原因是,浏览器需要先构建 CSSOM(CSS 对象模型)来确定页面的布局和样式,这样才能正确渲染页面。
  • CSSOM 构建:浏览器会下载并解析所有的 CSS 文件,创建一个与 DOM 对象模型(Document Object Model)并行的 CSSOM。CSSOM 是用于描述文档样式的结构化表示,和 DOM 一起用来构建渲染树(Render Tree)。
  • 阻塞渲染的原因:由于 CSS 可能会影响页面元素的显示方式,因此在没有完成 CSSOM 的构建前,浏览器无法正确绘制页面的内容。渲染树的构建依赖于 DOM 和 CSSOM 的完成。
3. JavaScript 的加载与执行
  • 遇到 <script> 标签:JavaScript 的处理方式对页面加载有重大影响。当浏览器遇到 <script> 标签时,它会暂停 HTML 文档的解析,直到脚本被下载并执行完毕。这是因为 JavaScript 可能会修改 DOM 或引入新的样式规则。
  • 同步脚本(Blocking Scripts):默认情况下,<script> 标签会阻塞后续的 HTML 解析和其他资源的加载,直到脚本执行完毕。因此,脚本放置在页面的不同位置会影响加载速度和用户体验。
  • 异步脚本(Async Scripts):通过在 <script> 标签中添加 async 属性,浏览器可以异步加载脚本文件,即脚本的下载与 HTML 的解析可以并行进行。然而,一旦脚本下载完毕,它将立即执行,可能会中断 HTML 解析。
  • 延迟脚本(Defer Scripts)defer 属性允许浏览器异步加载脚本,但它保证脚本在 HTML 完全解析后才执行。所有带 defer 属性的脚本按顺序执行,在 DOMContentLoaded 事件之后执行。
4. 构建渲染树与渲染过程
  • 渲染树构建(Render Tree Construction):当浏览器完成 DOM 和 CSSOM 的构建后,它会合并这两个模型生成渲染树。渲染树包含了页面上所有可见元素及其样式。
  • 布局阶段(Layout Phase):浏览器基于渲染树计算每个元素在屏幕上的位置和尺寸。这一过程也称为“回流”(Reflow)。
  • 绘制阶段(Painting Phase):在布局阶段完成后,浏览器将页面元素绘制到屏幕上。绘制是一个将渲染树的每个节点转换为实际像素的过程。
5. 关键事件:DOMContentLoaded 与 Load
  • DOMContentLoaded 事件:该事件在初始的 HTML 文档完全加载和解析完毕后触发,不等待 CSS、图片等其他资源的完全加载。这通常标志着页面的基础结构已准备好,适合用来初始化不依赖资源加载的 JavaScript 操作。
  • Load 事件Load 事件在页面及其所有资源(包括图片、样式表、框架等)完全加载后触发。此事件适合用来执行依赖于所有资源加载完成的操作,如图片幻灯片或富媒体内容。
6. 脚本的动态加载与资源优化
  • 动态资源加载(Dynamic Resource Loading):即使页面加载完成,JavaScript 仍然可以通过 AJAX(Asynchronous JavaScript and XML)、fetch API 或动态插入 <script> 标签来加载额外的资源。这些操作不会阻塞页面的初始加载,但可能会影响后续的用户交互体验。

  • 延迟加载(Lazy Loading):为了进一步优化加载速度,可以使用懒加载技术。懒加载推迟非关键资源(如图片、视频、第三方脚本等)的加载,直到用户需要它们时才加载。这减少了页面的初始加载时间,提高了用户的感知性能。

    关于延迟加载的方案-点击跳转

7. 影响加载时间线的最佳实践
  • 将 CSS 放在 <head>:CSS 是阻塞渲染的资源,最好将其放在文档的 <head> 中,以尽早启动它的加载和解析过程。
  • 将 JavaScript 放在文档底部或使用 asyncdefer:JavaScript 阻塞 HTML 解析,放置在文档底部或使用 asyncdefer 属性可以减少对页面加载的影响。
  • 使用内容分发网络(CDN):通过将常用的 JavaScript 库(如 jQuery、React 等)放在 CDN 上,可以提高资源的加载速度,因为用户可能已经从其他网站缓存了这些库。
  • 压缩和最小化资源:通过压缩和最小化 HTML、CSS 和 JavaScript 文件,可以减少文件大小,缩短加载时间。
  • 减少 HTTP 请求:合并 CSS 和 JavaScript 文件,使用图像精灵(Sprite)等方法可以减少网页的 HTTP 请求数量,从而加快加载速度 。
8.补充——为什么执行JS脚本会暂停文档的解析

浏览器在执行JavaScript(JS)脚本时会暂停对文档的解析,这是因为JavaScript的执行可能会改变页面的内容或结构。这样的设计是为了确保页面的解析和渲染顺序正确,以便用户能看到预期的内容和功能。以下是一些具体原因:

  1. JavaScript可能修改DOM: JavaScript脚本可以操作文档对象模型(DOM),例如添加、删除或修改元素。如果浏览器在JavaScript执行期间继续解析HTML文档,可能会导致页面状态的不一致。例如,如果脚本在运行时插入新的HTML内容,而浏览器没有暂停解析,那么插入的内容可能不会被正确处理。

  2. 保障脚本的依赖顺序: JavaScript脚本通常依赖于之前加载的内容和其他脚本。通过暂停解析,浏览器可以确保在执行某个脚本时,所有依赖的内容已经加载完成。例如,某个脚本可能依赖于页面中之前定义的元素或其他脚本。如果不暂停解析,这些依赖关系可能会被破坏,导致脚本运行失败或产生意外结果。

  3. 避免混乱的页面加载体验: 如果浏览器在执行脚本时不暂停解析,页面可能会一边加载一边修改,用户看到的内容会不断变化,体验不佳。通过暂停解析,浏览器可以确保脚本完成后再继续加载剩余的内容,这样用户看到的页面会更加稳定和一致。

  4. 保持一致性和可预测性: 暂停解析以执行JavaScript脚本可以确保页面内容按预期加载和呈现。如果脚本可以随时执行,开发者很难预测脚本在页面解析的哪个阶段执行,这会导致开发和调试困难。因此,通过暂停解析,浏览器为开发者提供了更可预测的行为。

为了解决因解析暂停而导致的页面加载时间增加的问题,现代浏览器支持异步脚本加载(使用asyncdefer属性),这允许脚本在后台加载,不阻塞文档解析,从而提高页面加载速度。


结论

理解 JavaScript 的加载时间线对于优化网页性能至关重要。通过合理安排 CSS 和 JavaScript 的加载顺序、使用异步和延迟技术、优化资源加载,可以显著提升网页的加载速度和用户体验。在现代 Web 开发中,这种优化方法不仅仅是性能调优的工具,更是打造高效、响应迅速的用户界面不可或缺的一部分。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值