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

<script>标签对HTML文件解析过程的影响以及async和defer属性的应用

在前端开发中,<script> 标签的 asyncdefer 属性会显著影响 JavaScript 脚本的加载和执行时机。下面结合示例代码,详细解析它们之间的区别:

1. 默认情况(无 async/defer

<script src="script.js"></script>
特性
  • 阻塞渲染:浏览器遇到 <script> 标签后,会立即暂停 HTML 解析,下载并执行脚本,直到脚本执行完毕才继续解析 HTML。
  • 执行顺序:按照标签在 HTML 中的出现顺序执行。
  • 适用场景:需要立即执行的脚本,或依赖于当前 DOM 的脚本。
示例
<!DOCTYPE html>
<html>
<head><title>默认脚本加载</title>
</head>
<body><div id="app">加载中...</div><!-- 阻塞渲染,直到 script.js 下载并执行完毕 --><script src="script.js"></script><div>其他内容</div>
</body>
</html>

2. async 属性

<script async src="script.js"></script>
特性
  • 异步下载:脚本的下载与 HTML 解析同时进行,不会阻塞渲染。
  • 立即执行:脚本下载完成后,会立即暂停 HTML 解析并执行脚本。
  • 执行顺序不确定:多个 async 脚本的执行顺序取决于下载完成的时间,与标签顺序无关。
  • 适用场景:独立的、不依赖于其他脚本或 DOM 的异步脚本(如广告、分析工具)。
示例
<!DOCTYPE html>
<html>
<head><title>async 脚本加载</title>
</head>
<body><div id="app">加载中...</div><!-- 不阻塞渲染,下载完成后立即执行 --><script async src="analytics.js"></script><div>其他内容</div>
</body>
</html>

3. defer 属性

<script defer src="script.js"></script>
特性
  • 异步下载:脚本的下载与 HTML 解析同时进行,不会阻塞渲染。
  • 延迟执行:脚本会在 HTML 解析完成后、DOMContentLoaded 事件触发前执行。
  • 执行顺序确定:多个 defer 脚本按标签在 HTML 中的出现顺序执行。
  • 适用场景:需要操作 DOM 或依赖于其他脚本的库(如 jQuery)。
示例
<!DOCTYPE html>
<html>
<head><title>defer 脚本加载</title><!-- defer 脚本会在 HTML 解析完成后按顺序执行 --><script defer src="jquery.js"></script><script defer src="app.js"></script>
</head>
<body><div id="app">内容</div>
</body>
</html>

ps:

在浏览器解析 HTML 的过程中,defer 脚本的执行先于 DOMContentLoaded 事件

执行顺序原理

  1. defer 脚本的特性

    • 带有 defer 属性的脚本会与 HTML 解析并行下载(不阻塞解析)。
    • 下载完成后不会立即执行,而是等待整个 HTML 文档解析完成(即 DOM 构建完成)后,再按脚本在 HTML 中的顺序依次执行。
  2. DOMContentLoaded 事件的触发时机

    • 当整个 HTML 文档解析完成(DOM 树构建完毕),且所有 defer 脚本执行完成后,才会触发 DOMContentLoaded 事件。

示例验证

<!DOCTYPE html>
<html>
<head><!-- defer 脚本:在 HTML 解析完成后执行 --><script defer src="defer-script.js"></script><script>// 监听 DOMContentLoaded 事件document.addEventListener('DOMContentLoaded', () => {console.log('DOMContentLoaded 事件触发');});</script>
</head>
<body><h1>测试执行顺序</h1>
</body>
</html>
// defer-script.js
console.log('defer 脚本执行');
输出顺序:
defer 脚本执行
DOMContentLoaded 事件触发

结论

defer 脚本的执行先于 DOMContentLoaded 事件
defer 的设计初衷就是保证脚本在 DOM 就绪后、DOMContentLoaded 之前执行,适合需要操作 DOM 且依赖执行顺序的场景(如加载 jQuery 后再执行依赖它的代码)。

执行时机对比图

HTML 解析         |---------------------------->|
默认脚本          |    下载并执行    |
async 脚本        |      下载       | 执行 |
defer 脚本        |      下载       |       | 执行
DOMContentLoaded  |---------------------------->|

关键区别总结

特性默认(无属性)asyncdefer
是否阻塞渲染
下载时机HTML 解析暂停与 HTML 解析并行与 HTML 解析并行
执行时机下载后立即执行下载完成后立即执行HTML 解析完成后执行
执行顺序按标签顺序不确定(下载完成顺序)按标签顺序
DOM 依赖需确保 DOM 已加载不依赖 DOM可依赖 DOM

最佳实践

  1. 优先使用 defer:对于需要操作 DOM 或依赖于其他脚本的代码,使用 defer
  2. 使用 async 加载独立脚本:对于不依赖其他资源的异步脚本(如第三方库),使用 async
  3. 内联脚本避免使用 async/deferasyncdefer 仅对外部脚本(src 属性)有效,对内联脚本无效。

兼容性

  • asyncdefer 均支持现代浏览器及 IE10+。
  • 若需兼容 IE9 及以下版本,需使用默认加载方式或通过 JavaScript 动态加载脚本。
http://www.dtcms.com/a/273585.html

相关文章:

  • 在 React Three Fiber 中实现 3D 模型点击扩散波效果
  • 车企战略投资项目管理的实践与思考︱中国第一汽车集团进出口有限公司战略部投资管理专家庞博
  • 台球 PCOL:极致物理还原的网页斯诺克引擎(附源码深度解析)
  • 软件设计师中级逻辑公式题
  • Ubuntu 24.04上安装 Intelligent Pinyin 中文输入法
  • Java算法 -蓝桥云课 -卖货
  • 【联合国国家指标 2025:HDI、GDP、POP、面积】数据集countries_metric - Sheet1.csv
  • C++迭代器失效
  • 深入剖析Spring Bean生命周期:从诞生到消亡的全过程
  • 羲和:一款诗词风格的摆件App
  • GitHub Copilot:产品经理提升工作效率的AI助手
  • 销售数据可视化分析项目
  • AI基建还能投多久?高盛:2-3年不是问题,回报窗口才刚开启
  • Lookahead:Trie 树(前缀树)
  • TCP详解——流量控制、滑动窗口
  • 【接口测试】07 Fiddler使用教程(图文详解)
  • Flutter、Vue 3 和 React 在 UI 布局比较
  • 20.缓存问题与解决方案详解教程
  • 【Java】【力扣】102.二叉树层序遍历
  • 前端抓包(不启动前端项目就能进行后端调试)--whistle
  • 什么是DOM存储
  • 05 rk3568 debian11 root用户 声音服务PulseAudio不正常
  • Typecho架构深度剖析:轻量级博客系统的设计哲学与实现原理
  • 前端性能与可靠性工程:我们度量什么?核心 Web 指标与工具入门
  • 【氮化镓】不同偏压应力下电荷俘获效应导致的P-GaN HEMT阈值电压不稳定性
  • Chromium 136 编译指南 - Android 篇:从Linux版切换到Android版(六)
  • 电子基石:硬件工程师的器件手册 (四) - 二极管:电流的单向阀与电路的守护神
  • SSL与HTTP概述
  • 神经网络的参数初始化
  • 【数据结构与算法】203.移除链表元素(LeetCode)图文详解