当前位置: 首页 > news >正文

JS中【async】和【defer】属性详解与区别

理解浏览器如何处理JavaScript以及相关的asyncdefer属性对于前端开发是非常重要的。以下是相关知识点的详细讲解:

1. 浏览器的解析和渲染过程

浏览器在加载网页时,会按照以下步骤解析和渲染内容:

  1. HTML解析: 浏览器从顶部开始逐行解析HTML文件,生成DOM树(Document Object Model),代表页面的结构。

  2. CSS解析: 同时,浏览器会解析CSS文件和内联样式,生成CSSOM(CSS Object Model),代表页面的样式。

  3. JavaScript执行: 当解析器遇到<script>标签时,默认会暂停HTML的解析和渲染,去执行脚本中的JavaScript代码。

  4. 页面渲染: 解析完所有内容并执行完所有脚本后,浏览器根据DOM树和CSSOM树渲染出页面。

2. 为什么JavaScript脚本会阻塞解析

JavaScript脚本可能会操作DOM或者改变页面内容,比如添加或删除元素、改变样式等。为了确保这些操作的正确性,浏览器在遇到<script>标签时会暂停HTML的解析。这样可以保证:

  • 顺序执行: 浏览器会严格按照脚本在HTML中的顺序来执行JavaScript代码,确保脚本间的依赖关系。

  • 页面一致性: 在脚本执行完成之前暂停解析可以防止在HTML文档解析的过程中发生不一致的情况。例如,如果脚本在解析过程中插入新元素,暂停解析可以确保这些新元素被正确处理。

3. asyncdefer属性

为了优化页面加载性能,HTML5引入了asyncdefer属性,用于控制脚本的加载和执行行为。

async 属性
  • 加载方式: 使用async属性的脚本是异步加载的,这意味着脚本会在后台加载,不会阻塞HTML文档的解析。
  • 执行时机: 一旦脚本加载完成,浏览器会立即执行它,这可能在HTML文档的解析完成之前。因此,async脚本的执行顺序无法保证,脚本之间也不应有依赖。
  • 适用场景: 适用于独立的脚本,比如广告、数据统计脚本,这些脚本不依赖于其他内容,也不改变页面结构。
<script src="script.js" async></script>
defer 属性
  • 加载方式: 使用defer属性的脚本也是异步加载的,类似于async,它们不会阻塞HTML文档的解析。
  • 执行时机: 与async不同,defer脚本会在HTML文档完全解析完毕后按顺序执行。这意味着即使脚本加载完成,它们也会等到文档解析结束才执行。
  • 适用场景: 适用于需要确保脚本顺序或依赖于整个文档的脚本。defer脚本通常用于初始化页面的JavaScript代码。
<script src="script.js" defer></script>

4. asyncdefer的区别

特性asyncdefer
加载方式异步异步
执行时机加载完成后立即执行HTML解析完成后按顺序执行
执行顺序不保证顺序保证顺序
适用场景独立脚本依赖脚本或初始化脚本

5. 使用示例

<!-- 使用async加载并执行独立的统计脚本 -->
<script src="analytics.js" async></script><!-- 使用defer加载并按顺序执行页面初始化脚本 -->
<script src="init1.js" defer></script>
<script src="init2.js" defer></script>

6. 总结

  • 浏览器在遇到<script>标签时会暂停HTML文档解析以执行JavaScript,这是为了保证文档加载和脚本执行的一致性。
  • async属性允许脚本在后台异步加载和立即执行,适用于独立、不依赖其他脚本的场景。
  • defer属性也允许脚本异步加载,但会在HTML解析完成后按顺序执行,适用于有依赖关系或初始化的场景。

使用asyncdefer可以优化页面加载性能,减少阻塞时间,提供更好的用户体验。理解它们的区别和应用场景可以帮更好地控制页面的加载行为。


http://www.mrgr.cn/news/19265.html

相关文章:

  • 4.3 Sensors -- onLongPress
  • C++ | Leetcode C++题解之第394题字符串解码
  • 数据结构之链表
  • Python Tkinter小程序
  • 分类预测|基于蜣螂优化极限梯度提升决策树的数据分类预测Matlab程序DBO-Xgboost 多特征输入单输出 含基础模型
  • 浏览器自动化测试的利器:Cypress
  • SPI总线协议详解
  • Golang | Leetcode Golang题解之第394题字符串解码
  • 高效异步编程:使用Python的asyncio库实现异步I/O操作
  • 我找到了一个让ChatGPT稳定通过草莓测试的方法,百试百灵!
  • 【conda】Conda 环境迁移指南:如何更改 envs_dirs 和 pkgs_dirs 以及跨盘迁移
  • 深度学习应用 - 语音识别篇
  • YoloV10改进策略:卷积篇|基于PConv的二次创新|附结构图|性能和精度得到大幅度提高(独家原创)
  • Java | Leetcode Java题解之第393题UTF-8编码验证
  • 9 自研rgbd相机基于rk3566之qt框架开发rgbd融合线程
  • pytorch pyro更高阶的优化器会使用更高阶的导数,比如二阶导数(Hessian矩阵)
  • 【嵌入式撸码】内存相关的大小尽量偶数对齐
  • J.U.C Review - 阻塞队列原理/源码分析
  • https和harbor仓库跟k8s
  • Steam游戏截图方法