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

<script> 标签的 async 与 defer 属性详解

<script> 标签的 async 和 defer 属性是控制 JavaScript 脚本加载与执行时机的关键机制,它们直接影响页面的渲染性能和用户体验。

正常情况下,浏览器会从顶部开始逐行解析 HTML、css文件,但是遇到 <script> 标签会暂停渲染,而去执行 javascript 代码,也就是说 JavaScript 执行会阻塞 DOM 构建,导致页面渲染延迟。

为了解决这个问题,因此HTML5引入了 async 和 defer 属性,用于控制脚本的加载和执行行为。

async和defer属性简介

使用 async 和 defer 属性的脚本都是异步加载的,都不会阻塞 HTML 文档的解析,但是他们的执行时机是不同的,下面来详细说明一下。

默认行为(无属性)

为了对比,我们需要清楚默认行为是怎样的。

<script src="script.js"></script>
执行时机

同步加载和执行。

流程:
  1. HTML 解析暂停。
  2. 下载脚本(阻塞主线程)。
  3. 执行脚本。
  4. 恢复 HTML 解析。
影响:

页面渲染会延迟,尤其是在脚本体积大或网络慢的时候。

async 属性

<script async src="script.js"></script>
执行时机

异步加载,立即执行。

流程

  1. HTML 解析继续,不阻塞。
  2. 并行下载脚本(不阻塞主线程)。
  3. 脚本下载完成后,立即暂停 HTML 解析并执行脚本。
  4. 执行完毕后,恢复 HTML 解析。
特点:
  • 多个 async 脚本的执行顺序不确定(取决于下载完成时间)。
  • 不保证在 DOMContentLoaded 事件前执行。
适用场景:

独立脚本(如广告、分析工具),不依赖 DOM 或其他脚本。

defer 属性

<script defer src="script.js"></script>
执行时机:

异步加载,延迟执行。

流程:
  1. HTML 解析继续,不阻塞。
  2. 并行下载脚本(不阻塞主线程)。
  3. 等待 HTML 解析完成(DOMContentLoaded 事件触发前),按引入顺序执行脚本。
特点:
  • 多个 defer 脚本按书写顺序执行。
  • 保证在 DOMContentLoaded 事件前执行完毕。
适用场景:

需要操作 DOM 的脚本(如交互逻辑)。
依赖其他脚本的模块(如库的初始化)。

三者表格对比

特性无属性(默认)asyncdefer
是否阻塞 HTML 解析
下载时机立即并行(异步)并行(异步)
执行时机下载后立即执行下载完成后立即执行HTML 解析完成后(按顺序)
执行顺序按引入顺序不确定(按下载完成时间)按引入顺序
DOMContentLoaded 关系阻塞事件触发可能在事件后执行在事件前执行
适用场景一般场景独立脚本依赖脚本或初始化脚本

代码示例:

<!DOCTYPE html>
<html>
<head><!-- 1. 立即执行,阻塞后续内容 --><script src="critical.js"></script><!-- 2. 并行下载,HTML 解析完成后按顺序执行 --><script defer src="library.js"></script><script defer src="app.js"></script><!-- 3. 并行下载,下载完成后立即执行(顺序不确定) --><script async src="analytics.js"></script>
</head>
<body><!-- DOM 内容 -->
</body>
</html>

注意事项

  1. 内联脚本无效
    async 和 defer 仅对外部脚本(src 属性)有效,对内联脚本无影响。
  2. 混合使用时的优先级
    async 和 defer 同时存在时,行为等同于 async(现代浏览器)。
    旧版浏览器可能忽略 defer,建议避免混用。
  3. 动态插入的脚本
    动态创建的脚本默认行为为 async,可通过 script.async = false 修改。
  4. 兼容性
    async:IE 10+,现代浏览器均支持。
    defer:IE 9+,现代浏览器均支持。

性能优化建议

  • 关键脚本:放 中,确保尽早执行(如 CSSOM 阻塞脚本)。
  • 非关键脚本:使用 defer 或 async,避免阻塞渲染。
  • 依赖关系脚本:使用 defer 并按依赖顺序引入。
  • 独立脚本:使用 async 加速执行(如广告、第三方插件)。
http://www.xdnf.cn/news/987571.html

相关文章:

  • 《Linux C编程实战》笔记番外:如何避免子进程成为僵尸进程
  • 阿里云unbantu、Flask部署模型的一个错误
  • 安卓+苹果端签名教程
  • SiteAzure:文章删除后,前台还能搜索到
  • HarmonyOS - UIObserver(无感监听)
  • TF-IDF算法的代码实践应用——关键词提取、文本分类、信息检索
  • 帆软 BI 从入门到实战全攻略(一):安装激活与添加数据
  • 大量RPM仓库管理指南:更新与批量获取实战手册
  • VS2017----打开ui文件几秒后闪退
  • 汇编(函数调用)
  • 刷新网站 favicon 的几种方法
  • 医院重症监护系统 ICU重症病房管理系统 重症监护软件
  • QT第一课 —— 设置CMake路径
  • Rust:在Windows上安装
  • BEV和OCC学习-7:mmdet3d 3D检测demo测试
  • 剑指offer21——反转链表
  • 使用html写一个倒计时页面
  • 将模型保存到kaggle中的model中
  • 解码 K-Means 聚类:开启数据星河的炫酷聚类新纪元
  • 前端项目主题切换
  • 解锁Wi-SUN潜能!移远通信发布KCM0A5S模组,点亮智慧城市新图景
  • 关于有害的过度使用 std::move
  • Delphi 获取 XP系统 mac地址
  • Selenium工作原理
  • 【leetcode】36. 有效的数独
  • 利用递归来遍历树
  • Android学习之Window窗口
  • 一个数组样式上要分成两个
  • Unity UGUI GraphicRaycaster.Raycast详解
  • 免费开源的微信开发框架