【HTML】defer 和 async 属性在 script 标签中分别有什么作用?

需要这两个属性的原因?

首先我们要知道的是,浏览器在解析 HTML 的过程中,遇到了 script 元素是不能继续构建 DOM 树的。

  • 它会停止解析构建,首先去下载 js 代码,并且执行 js 的脚本;
  • 只有在等到 js 脚本执行结束之后,才会继续解析 html,构建 DOM 树。

那为什么要这样做呢?

  • 因为 js 的作用之一就是操作 DOM,并且可以修改 DOM;
  • 如果等到 DOM 树构建完成并且渲染后再去执行 js,就会造成严重的回流重绘,影响页面性能;
  • 所以,在遇到 script 标签的时候,浏览器采取了先加载执行后构建 DOM 树的方案。

虽然是解决了回流和重绘的问题,但这又产生了新的问题!(解决一个问题产生了新的问题😂)

在现在的网页开发模式中(Vue、React),往往 js 脚本比 HTML 结构更“重”,需要加载和处理的时间更长。

这样就会导致页面的解析阻塞(在脚本完成下载、执行之前,用户在界面上什么都看不到)。

为了解决上面的问题,script 元素给我们提供了两个属性来处理:deferasync

defer 的作用

defer 翻译过来就是延迟的意思

defer 属性告诉浏览器不要等待脚本下载,而是继续解析 HTML、构建 DOM Tree。

  • 脚本会又浏览器来进行下载,但是不会阻塞 DOMTree 的构建过程;
  • 如果脚本提前下载好了,它会等待 DOM Tree 构建完成,在 DOMContentLoaded 事件之前执行 defer 中的代码。

下面举个例子:

我们创建了一个 defer.js 文件并在脚本执行的时候添加了 defer 属性,最后我们可以看到 DOMContentLoaded 会等待 defer 中的代码先执行完成。

在这里插入图片描述
在这里插入图片描述
另外我们要注意的是,多个 defer 的脚本是可以保持顺序执行的。

在这里插入图片描述
在这里插入图片描述
从某种角度来说,defer 是可以提高页面性能的,并且推荐把带有 defer 属性的 script 标签放到 heade 元素中。

async 的作用

async 翻译过来是异步的意思

async 的特性和 defer 有些类似

  • 浏览器不会因为 async 脚本的下载而阻塞(和 defer 类似)
  • 但是在带有 async 属性的脚本会在下载完成后立即执行,并且不能保证在 DOMContentLoaded 之前或者之后执行,我们要知道在脚本执行的时候是会阻塞 DOMTree 的构建。
  • 还有就是 async 脚本是不能保证顺序的,它是独立下载、独立运行,不会等待其他脚本;

在这里插入图片描述
在这里插入图片描述

具体的执⾏时机图解

绿色-HTML 解析;黑色-停止 HTML 解析;黄色-脚本下载;棕色-脚本执行;
在这里插入图片描述

总结

script 标签的 defer 和 async 属性都是用来控制外部脚本的加载和执行方式的,他们对于改善页面加载非常有帮助。

但是他们的机制并不相同:

  • defer 下载不会阻止 DOM 的构建,但是在 DOMTree 构建完成后,在 DOMContentLoaded 事件之前执行,并且 defer 脚本的执行是有序的。
  • async 下载同样不会阻止 DOM 的构建,但是不会保证在 DOMcontentLoaded 之前或者之后执行,也不能保证顺序,它的每个脚本都是独立的。

所以他们的应用场景是这样的:

  • defer 通常用于需要在文档解析后操作 DOM 的 js 代码,并且对多个脚本文件有顺序要求
  • async 通常用于独立的脚本,对其他脚本,甚至对 DOM 没有依赖的脚本。

在现代化的框架开发中,已经不需要我们手动设置 async 和 defer 了,在使用脚手架的时候,一遍会根据我们需要自动加上 defer 属性,某些特殊场景下,比如第三方分析工具或者是广告追踪脚本等,需要我们自己加上 async 属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1560239.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

selenium自动化测试之Junit

1. 常用的注解 将junit的索引添加到pom文件&#xff1a; <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId&…

CPU超线程技术是什么,怎么启用超线程技术

超线程技术是一种允许单个物理CPU核心模拟成两个逻辑核心的技术&#xff0c;从而提升处理器的并行性能和效率。以下是对超线程技术的详细介绍&#xff1a; 基本概念&#xff1a;超线程&#xff08;Hyper-Threading&#xff0c;HT&#xff09;是Intel公司研发的一种技术&#x…

QD1-P12 HTML常用标签:表格

本节学习 HTML常用标签&#xff1a;表格标签table ‍ 本节视频 www.bilibili.com/video/BV1n64y1U7oj?p12 ‍ 知识点1 表格的基本结构 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>P12-表格标签</title><…

SpringBoot整合web中使用jsp

1、在pom.xml文件中导入jsp依赖的jar包&#xff0c;一个是jstl标签&#xff0c;一个是jsp的引擎 <dependency><groupId>org.apache.taglibs</groupId><artifactId>taglibs-standard-spec</artifactId><version>1.2.5</version> <…

如何在RuoYi-Vue项目中去除`/dev-api`前缀

前言 在使用RuoYi-Vue框架进行Web应用开发时&#xff0c;有时会遇到API路径需要特定前缀的问题。例如&#xff0c;在某些情况下&#xff0c;开发者可能希望移除或更改默认的/dev-api前缀。 问题描述 当使用YApi直接请求后台接口时&#xff0c;无需添加/dev-api前缀。在生成和…

Java入门——变量

变量和内存紧密联系在一起&#xff0c;主要通过以下方式实现关联&#xff1a; 一、变量的定义与内存分配 变量声明&#xff1a; 当在编程语言中声明一个变量时&#xff0c;编译器或解释器会根据变量的类型在内存中为其分配一块特定大小的空间。 例如&#xff0c;在 C 语言中声明…

包材推荐中的算法应用|得物技术

目录 一、业务背景 二、算法架构 规则算法 三、算法原理 装箱装袋 四、衍生应用 切箱合包箱型设计包装方案推荐 五、作者结语 一、业务背景 任何一家电商的商品出库场景中&#xff0c;都涉及到打包——即把订单中的商品用包材进行包裹&#xff0c;常见的打包方式有装袋和装箱。…

算法复杂度 (数据结构)

一. 数据结构前言 1.1 什么是数据结构 数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的集合。没有一种单一的数据结构对所有用途都有用&#xff0c;所以我们要学各式各样的数据结构&#xff0c;如&#xff1…

[Qt] 信号与槽:深入浅出跨UI与跨线程的信号发送

文章目录 如何自定义信号并使用自定义信号的步骤1.使用 signals 声明信号2. 信号的返回值是 void3. 在需要发送信号的地方使用 emit4. 使用 connect 链接信号和槽5. 完整代码示例总结 如何跨UI发送信号Qt跨UI发送信号机制详解案例概述Qt 信号与槽机制简介代码逻辑详解主窗口 Wi…

进程通讯方式区别(从不同角度看)

*常用到的不同主机间进程通讯&#xff1a;Socket。比如&#xff1a;host和引擎间socket指令通讯、分派和复判之间指令通讯&#xff1b; *共享内存&#xff1a;在Windows系统中&#xff0c;共享内存的实现通常有以下几种方式&#xff1a; 1.内存映射文件(最常用)&#xff1a;(…

计算机毕业设计 医院预约挂号系统的设计与实现 Python毕业设计 Python毕业设计选题【附源码+安装调试】

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

【01】手把手教你0基础部署SpringCloud微服务商城教学-Mybatis篇(上)

序言&#xff1a; 微服务是一种软件架构风格&#xff0c;它是以专注于单一职责的很多小型项目为基础&#xff0c;组合出复杂的大型应用。 想学习SpringCloud搭建项目&#xff0c;首先我们需要学习的就是Mybatis和Docker。 大家在日常开发中应该能发现&#xff0c;单表的CRUD…

没人告诉你的职场人情世故

看到前同事在群里分享的新年开工遭遇&#xff0c;真是让人感同身受。 第一天就遇到挫折&#xff0c;因为工作做得太快、太早交付&#xff0c;结果反被领导批评&#xff0c;还得重做&#xff0c;头大如斗。这不就提醒我们得时时刻刻记着职场里的那些不成文的规矩吗&#xff1f;…

【C++】常用数据结构纲要(简易版)

非静无以成学。——诸葛亮 数据结构概括 1、什么是数据结构呢&#xff1f;2、讲述过的结构2、1、前言2、2、树->二叉树->两种平衡二叉树2、3、单链表->双链表->带有哨兵位的链表 3、B树3、1、概念及图示3、2、B树数据处理3、2、1、查找3、2、2、插入 4、哈希表4、1…

测试点总结 | 搜索功能如何测试?

这里仅针对通用搜索框的常见测试点进行总结分享&#xff0c;实际工作中需结合搜索功能的背景业务需求及其他依赖条件来综合设计测试点。 一、功能实现部分 &#xff08;1&#xff09;如果支持模糊查询&#xff0c;搜索名称中任意一个字符是否能搜索到 对于支持模糊查询的搜索…

猫头虎分享已解决Bug || AssertionError: Torch not compiled with CUDA enabled 解决方案

&#x1f42f; 猫头虎分享已解决Bug || AssertionError: Torch not compiled with CUDA enabled 解决方案 摘要 今天猫头虎收到粉丝提问&#xff1a;“猫哥&#xff0c;我在使用 PyTorch 进行 AI大模型训练 时&#xff0c;出现了 AssertionError: Torch not compiled with CUD…

10.9 LeetCode 3289 0001 3295

思路&#xff1a; 1、用数组下标来表示是否出现过&#xff0c;初始为 0&#xff0c;出现则加 1&#xff0c;判断大于等于 2 的数字即为多次出现。 2、先将数组排序&#xff0c;依次遍历排序过的数组&#xff0c;若第 i 位与第 i1 位相等&#xff0c;则说明是重复数字。 class …

mybatis解析异常

1.问题现象 Caused by: org.springframework.dao.TransientDataAccessResourceException: Error attempting to get column sale_id from result set. Cause: java.sql.SQLException: Cannot convert value from column 19 to TIMESTAMP. 造成原因:需要给表中中增加字段以满…

审稿人喜欢什么样的Novelty?

在学术出版的世界里&#xff0c;“novelty”&#xff08;创新性&#xff09;是一个被频繁提及的词汇。它似乎是衡量一篇文章价值的黄金标准。然而&#xff0c;当我们深入挖掘这个概念时&#xff0c;会发现所谓的创新性并不是那么绝对。今天&#xff0c;我们就来聊聊审稿人眼中的…

No.15 笔记 | CSRF 跨站请求伪造

目录 一、基础知识 &#xff08;一&#xff09;cookie 和 session、同源策略 &#xff08;二&#xff09;CSRF 原理 二、CSRF 类型 &#xff08;一&#xff09;GET 类型 &#xff08;二&#xff09;POST 类型 三、CSRF 实例讲解 &#xff08;一&#xff09;真实案例 &am…