JavaScript中script元素的async和defer属性

本文深入探讨了HTML中script标签的三种加载方式:默认、async及defer,详细阐述了它们对页面渲染流程的影响,以及如何优化脚本加载以提升网页性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先来试个一句话解释仨,当浏览器碰到 script 脚本的时候:

1.<script src="script.js"></script>

没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行,HTML暂停

2.<script async src="script.js"></script>

有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。HTML元素与.js加载并行,.js执行时候HTML元素暂停

3.<script defer src="myscript.js"></script>

有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。HTML元素与.js加载并行,.js等HTML元素执行完后再执行

async和defer只对外部脚本文件有效。

配合下面图进行理解:
在这里插入图片描述
参考文章:
https://segmentfault.com/q/1010000000640869
https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html

<think>首先,用户的问题是:"请问前端script标签asyncdefer属性的区别及使用场景"。这是基于提供的引用内容来回答的。我的角色:我需要遵循系统级指令:-所有行内数学表达式用$...$(但在这个主题中,可能没有数学表达式)。-独立公式用$$...$$(同样,可能不适用)。-LaTeX语法正确(如果使用)。-使用中文回答。-生成相关问题。-回答中引用的段落末尾自然地添加引用标识,例如[^1]。用户可见层的指令:-回答结构清晰,帮助用户逐步解决问题。-尽量保证回答真实可靠。主题是关于前端script标签中的asyncdefer属性的区别及使用场景。我有五个引用:-[^1]讨论了asyncdefer的作用。-[^2]覆盖了默认情况、asyncdefer。-[^3]简单对比了deferasync的区别。-[^4]提供了优化建议适用场景。-[^5]解释了差异,包括阻塞行为。我需要结构化回答:1.**结构清晰**:逐步解释。首先介绍基本概念,然后区别,最后使用场景。2.**参考引用**:在相关内容后自然地添加引用标识,确保引用恰当。3.**生成相关问题**:在回答结束后,添加“相关问题”部分。大纲回答:-**引言**:简要介绍asyncdefer的重要性。-**基本概念**:-解释默认script行为(无asyncdefer)。-定义async属性。-定义defer属性。-**主要区别**:-加载行为:两者都是异步加载,不阻塞HTML解析。-执行顺序:-async:加载后立即执行,不保证顺序。-defer:加载后延迟到DOM解析完成后执行,保持顺序。-阻塞情况:-async可能会阻塞HTML解析。-defer不会阻塞HTML解析。-**使用场景**:-根据引用:当脚本不依赖于其他脚本或DOM时用async;当脚本依赖于DOM或需要顺序执行时用defer。-优化建议。-**总结**。-**生成相关问题**:在“相关问题”部分列出几个相关的问题。使用中文回答:整个响应用中文撰写。生成相关问题:-基于主题,生成3-5个相关的问题,比如性能影响、兼容性、最佳实践等。添加引用:在讨论相关点时自然地引用。例如:-当引用加载行为时,“如引用[5]指出,脚本加载是异步的...”-结束时确保引用标识是自然的。回应结构:1.以清晰的结构呈现。2.解释差异:执行顺序、阻塞、依赖关系。3.对比表可能有帮助:如引用[4]有一个表格。4.保持真实可靠:使用引用内容来支撑论点。最终输出:-回答部分。-§§相关问题§§部分。现在,起草响应。</think> ### 前端 script 标签 async defer 属性的区别及使用场景 在前端开发中,JavaScript脚本通过 `<script>` 标签加载时,`async` `defer` 属性用于优化页面性能用户体验。它们都能避免脚本加载阻塞HTML解析,但在执行顺序执行时机上有显著差异。基于提供的信息(引用[1]-[5]),我将一步步解释它们的区别及实际使用场景,确保内容真实可靠。 #### 基本概念 在讨论 `async` `defer` 前,先了解默认行为: - **默认行为(无属性)**:当浏览器遇到 `<script>` 标签时,它会**暂停HTML解析**,等待脚本加载执行完成后才继续解析文档。这可能导致页面渲染延迟、白屏时间长,影响用户体验[^5][^2]。 - **异步加载的本质**:`async` `defer` 都使脚本**加载过程异步化**,由网络进程负责,不阻塞HTML解析。但脚本**执行过程**仍然是同步的(占用渲染进程)[^5]。 #### async defer 的核心区别 下面比较两者的关键差异,基于它们的定义行为: | 属性 | 加载行为 | 执行顺序 | 执行时机 | 是否阻塞HTML解析 | 依赖关系 | |------|----------|----------|----------|------------------|----------| | **async** | 异步加载(不阻塞HTML解析) | **不保证顺序**:脚本加载完成后立即执行,谁先加载谁先执行。 | 加载完成后立即执行,可能在DOM解析前或期间。 | **可能阻塞**:执行脚本时可能占用渲染进程,短暂中断HTML解析。 | **不推荐依赖DOM或其他脚本**:执行顺序不确定,易导致错误。 | | **defer** | 异步加载(不阻塞HTML解析) | **保证顺序**:脚本按在HTML中出现的顺序执行,但延迟到DOM解析完成后执行。 | 延迟到HTML解析完全结束、DOMContentLoaded事件触发前执行。 | **不阻塞**:执行过程不影响HTML解析。 | **推荐依赖DOM或其他脚本**:确保所有脚本按序执行,适合需要DOM操作的场景。 | 关键区别总结: - **执行顺序**:`async` 可能导致脚本乱序执行(如加载较快的脚本先执行),而 `defer` 严格保持HTML文档顺序执行,适合脚本有依赖关系的情况[^3][^5]。 - **执行时机**:`async` 脚本一加载完就执行,可能在DOM加载中途;`defer` 脚本只在DOM解析完成后才执行,发生在`DOMContentLoaded`事件之前[^1][^2]。 - **阻塞风险**:`async` 的执行阶段可能短暂阻塞HTML解析(如脚本较大时),但 `defer` 几乎不会阻塞,除非脚本执行耗时过长[^5][^4]。 - **依赖处理**:`defer` 更适合需要访问DOM元素的脚本,因为它确保执行时DOM已就绪;而 `async` 用于完全独立的脚本,避免因为顺序问题引发bug[^3][^4]。 #### 使用场景实用建议 根据优化经验业务需求,合理选择属性可以提升页面加载速度稳定性。基于引用内容,推荐以下场景: 1. **使用 `async` 的场景**: - **独立脚本或不依赖DOM的脚本**:例如第三方分析工具(如 Google Analytics)、广告脚本、独立组件库。这些脚本不需要等待页面DOM构建,且顺序无关紧要。加载后立即执行,减少整体延迟[^4][^1]。 - **性能优化**:对于轻量级脚本或资源,`async` 能快速执行而不破坏用户体验。但需测试兼容性(如旧浏览器支持有限)[^2][^5]。 - **代码示例**: ```html <script async src="analytics.js"></script> ``` 2. **使用 `defer` 的场景**: - **依赖DOM或其他脚本的脚本**:例如主应用脚本、需要操作DOM的插件或框架(如 jQuery)。`defer` 保证所有脚本按序在DOM就绪后执行,避免"元素未定义"错误[^1][^4]。 - **提高用户体验**:在页面内容渲染后加载关键脚本,减少白屏时间,适用于需要内容优先的场景。 - **代码示例**: ```html <script defer src="vendor.js"></script> <script defer src="app.js"></script> <!-- app.js 依赖 vendor.js 时安全 --> ``` 3. **通用优化技巧**: - **避免混合使用**:在同一页面混用 `async` `defer` 可能导致意外行为,优先选择其中一种[^1]。 - **兼容性测试**:`defer` `async` 在大多数现代浏览器中支持良好,但在IE9及以下需测试备用方案。引用[2]建议使用工具(如Lighthouse)验证性能影响[^2][^5]。 - **默认建议**:当不确定时,优先用 `defer` 以确保安全顺序;而三方工具首选 `async` 以减少阻塞[^4][^3]。 #### 总结 `async` `defer` 都通过异步加载提升性能,但 `async` 适合独立、无依赖的脚本,而 `defer` 更适合依赖DOM或顺序执行的脚本。正确使用时,能显著减少页面加载时间(如通过优化First Contentful Paint指标)。引用[5]强调,异步加载是现代前端优化的核心策略之一[^5]。实践中,开发者应根据脚本特性需求权衡选择。 如需深入了解实现细节,可参考引用[1][4]的示例代码优化策略[^1][^4]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值