前端性能优化-script标签中的async与defer

news2025/1/11 8:11:48

前言

当浏览器解析 DOM 时候,遇到 script 标签时,会暂停 DOM 的解析,先加载并执行 script 中的代码,然后再继续 DOM 的解析。

比如

<script>
  window.env = {
    version: "production",
  };
</script>

上面的代码的处理顺序如下:

  1. 浏览器解析到 script 标签时,会暂停 DOM 的解析
  2. 加载并执行 script 中的代码
  3. 执行完毕后,触发 script 的 load 事件
  4. 继续 DOM 的解析

这样会导致页面的加载和渲染被阻塞,影响用户体验。

async 和 defer 是用于在 HTML 中加载外部 JavaScript 脚本的两个属性,它们可以帮助优化页面加载和脚本执行的顺序,从而提高页面的性能。

defer

defer 是 HTML 解析完才会执行。如果是多个,按照加载的顺序依次执行。defer 脚本会在 DOMContentLoaded 和 load 事件之前执行

当脚本依赖其他脚本或需要在 DOM 解析后执行时,可以考虑使用 defer 属性.

一些使用场景:

  • DOM 操作: 如果你的脚本需要操作页面的 DOM 元素,确保它在页面完全解析后再执行。这样可以避免在脚本执行时尝试访问尚未加载的 DOM 元素。

  • 依赖其他脚本: 如果你的脚本依赖于其他已加载的脚本,为了确保正确的执行顺序,可以使用 defer。这样可以避免在依赖脚本未加载完成时尝试执行。

  • 初始化代码: 如果你的脚本负责初始化应用程序或页面的某些功能,最好在 DOM 解析完成后再运行。这可以确保你的脚本在正确的上下文中执行,以免因为未完全加载的 DOM 而出现问题。

一个具体的业务使用场景是课件列表首页,二级页面课件解析需要依赖一个很大的 js 库,且该页面有很大概率被打开,这种情况下可以 defer 加载

async

async 会在脚本加载完之后立即执行。如果是多个,执行顺序和加载顺序无关。async 会在 load 事件之前执行,但并不能确保与 DOMContentLoaded 的执行先后顺序。

当脚本不依赖其他脚本且不需要等待 DOM 解析时,可以考虑使用 async 属性.

  • 分析或追踪代码: 如果你有一些用于分析用户行为或追踪页面性能的代码,这些代码通常不会直接操作 DOM,而是在页面加载时发送数据到服务器。这样的代码不会受到等待 DOM 解析的限制,可以使用 async 加载

  • 独立组件: 如果你编写的 JavaScript 脚本是独立的组件,不依赖于其他脚本或 DOM 解析,可以使用 async。例如,一些独立的小部件或插件,它们可能只需要自己的逻辑而不涉及整个页面的结构

  • 异步加载内容: 如果你希望在页面加载完成后异步加载一些内容(例如通过 AJAX 或 Fetch 请求),这些请求的响应不会影响页面的初始渲染,可以使用 async

script

不是所有的 script 都需要加上 defer 或者 async 属性,需要根据实际情况来决定是否使用。

  • 内联脚本: 如果你的脚本很小并且是内联的(即直接在 HTML 文件中嵌入),则它们会在解析到 script 标签时立即执行,不需要考虑 async 或 defer

  • 不涉及 DOM 操作的脚本: 如果你的脚本只是进行一些计算或逻辑处理,与页面的 DOM 结构无关,那么加载顺序可能不是关键,你可以根据需要决定是否使用 async 或 defer。

  • 脚本加载顺序无关紧要的情况: 如果脚本之间的加载顺序对页面的功能没有太大影响,也可以根据需要灵活选择是否使用 async 或 defer。

  • 独立的脚本: 如果你的脚本是独立的,不依赖于其他脚本,而且也不需要等待 DOM 解析完成,可以考虑使用 async,或者将脚本放在页面的末尾,不使用 async 或 defer

总结

类型执行顺序是否阻塞执行适用场景
script在 HTML 中的顺序-
script defer在 HTML 中的顺序依赖其他脚本/DOM 操作
script async网络加载的顺序三方工具/独立组件/异步加载内容

本文首发于个人博客前端开发笔记,由于笔者能力有限,文章难免有疏漏之处,欢迎指正

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

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

相关文章

KVM——虚拟机添加设备与挂载磁盘

目录 一. 图形化方式添加设备 1. 添加磁盘 2. 添加网卡 二. 命令行形式添加设备 方式一&#xff1a; 方式二&#xff1a; 磁盘格式raw和qcow2 raw格式 qcow2格式 如何选择 挂载磁盘 一. 图形化方式添加设备 1. 添加磁盘 2. 添加网卡 先关机 给宿主机添加一块网…

华南理工大学-大学物理实验 迈克尔逊干涉仪

迈克尔逊干涉仪的调整与使用 引言 迈克尔逊( Albert Abrham Michelson, 1852-1931) , 著名的实验物理学家,近现代干涉仪的开山鼻祖。他设计了至今仍在广泛应用的迈克尔逊干涉仪。该仪器设计非常巧妙,测量极其精密,是近代许多干涉仪的基础。迈克尔逊当时设计该仪器的目的之…

HCIA复习 | HCIP基础

目录 Days01&#xff08;24.8.1&#xff09; IPv4 Header OSI七层模型 TCP、UDP数据结构 TCP/IP模型 OSI模型与TCP/IP模型区别 ARP Days02&#xff08;24.8.2&#xff09; 交换机 封装和解封装 IPv6 Header 路由 RIP Days01&#xff08;24.8.1&#xff09; IPv4 …

【面试题】【简历版】完整版

一、Java 基础 java 面向对象特性 封装&#xff08;Encapsulation&#xff09;&#xff1a; public class Student {// 将name和age封装起来private String name;private int age;// 提供方法设置和获取这些属性public void setName(String name){this.name name;}public Str…

JavaEE: 查看线程信息

示例用代码 public class Main {static class MyThread extends Thread {Overridepublic void run() {while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}public st…

基于Java+SpringBoot+Vue的网上超市的设计与实现

基于JavaSpringBootVue的网上超市的设计与实现 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f34…

canal监听mysql增量数据发布到rabbitmq

canal工作原理 canal 依靠mysql主从备份的原理&#xff0c;模拟 MySQL slave 的交互协议&#xff0c;伪装自己为 MySQL slave &#xff0c;向 MySQL master 发送dump 协议MySQL master 收到 dump 请求&#xff0c;开始推送 binary log 给 slave (即 canal )canal 解析 binary …

python模块01-pymysql数据库连接查询

PyMySQL 是用于连接 MySQL 服务器的一个库 1 安装&#xff1a; pip install pymysql 2 数据库连接 conn pymysql.connect(host"127.0.0.1",port3306,user"localhost",password"123456",charset"utf8",cursorclassDictCursor ) cur…

Redisson看门狗机制和mulitLock原理保姆级别

Redisson看门狗机制 这段代码主要实现了异步处理一个任务&#xff0c;并根据任务结果来执行不同的操作。 首先&#xff0c;调用handleNoSync方法进行异步处理&#xff0c;并返回一个表示异步计算结果的CompletionStage<Long>对象&#xff0c;这里使用了threadId和ttlRe…

mathtype7.8永久激活码下载并安装激活MathType7.8破解版

“我好像被数学公式PUA了……” 最近&#xff0c;有位朋友跟我吐槽&#xff1a;自己每次做数学题、写论文&#xff0c;只要遇到复杂的公式和符号&#xff0c;就会特别焦虑。她觉得&#xff0c;自己好像被数学公式PUA了。 “明明知道它很重要&#xff0c;但就是不想面对它。” 其…

[Git][多人协作][下]详细讲解

目录 1.不同分支下多人协作2.远程分⽀删除后&#xff0c;本地git branch -a依然能看到 1.不同分支下多人协作 ⼀般情况下&#xff0c;如果有多需求需要多⼈同时进⾏开发&#xff0c;是不会在⼀个分⽀上进⾏多⼈开发&#xff0c;⽽是⼀个需求或⼀个功能点就要创建⼀个feature分…

CSS技巧专栏:一日一例 19 -纯CSS实现超酷的水晶按钮特效

CSS技巧专栏:一日一例 19 -纯CSS实现超酷的水晶按钮特效 今天给大家分享一个纯CSS按钮水晶按钮,效果很赞,希望对大家有所帮助。 本例图片 案例分析 这个按钮看起来效果很赞,我们分析一下它由几个层组成: 1. 按钮本体:渐变层+按钮文字 2.用before伪元素实现高光层+内…

Visual Studio 和 Visual Studio Code 的比较与应用偏向

Visual Studio 和 Visual Studio Code&#xff08;VS Code&#xff09;是微软开发的两个不同的开发工具&#xff0c;各有特点和优势&#xff0c;适用于不同的开发需求。下面是详细的比较和在实际应用中的偏向。 功能和特性 Visual Studio 完整的IDE&#xff1a;支持多种编程…

reNgine:终极 Web 侦察和漏洞扫描器

reNgine 是一个针对 Web 应用程序的开源自动侦察框架&#xff0c;专注于高度可配置和简化的侦察过程。 reNgine 的开发是为了克服传统侦察工具的限制。它是漏洞赏金猎人、渗透测试人员和企业安全团队的不错选择&#xff0c;可以自动化和完善他们的信息收集流程。 reNgine 是作为…

LeetCode 热题 HOT 100 (019/100)【宇宙最简单版】[创作中]

【链表】No. 0142 环形链表 II【中等】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&#…

AutoGPT 最最最新安装教程

介绍 本指南将帮助您为项目设置服务器和构建器。 先决条件 要设置服务器&#xff0c;您需要安装以下内容&#xff1a; Node.jsPython 3.10 检查是否已安装 Node.js 和 Python 您可以通过运行以下命令来检查是否已安装 Node.js&#xff1a; node -v您可以通过运行以下命…

剪画小程序:录音,怎么一键变成文字!

在学习的道路上&#xff0c;我们总是不断地参加各种讲座、研讨会&#xff0c;渴望汲取更多的知识。 但有时候&#xff0c;一场精彩的讲座结束后&#xff0c;想要回顾其中的重点内容&#xff0c;却发现仅凭记忆难以完整重现。 又或者在与朋友的深度交流中&#xff0c;大家碰撞出…

套接字编程

网络套接字编程 先将数据通过os&#xff0c;将数据发送到目标主机&#xff08;手段&#xff09;TCP/IP协议完成&#xff0c;再在本主机将收到的数据推送到自己上层指定的进程&#xff0c;这时候网络通信本质上就成了进程间的通信。其中ip地址可以标识互联网上唯一的一台主机&a…

Codeforces Round 964 (Div. 4) A~G

封面原图 画师ideolo A - AB Again? 题意 给你一个两位数&#xff0c;把他的个位和十位加起来 代码 #include <bits/stdc.h> using namespace std; typedef long long ll; typedef double db; typedef pair<int,int> pii; typedef pair<ll,ll> pll;voi…

嵌入式学习之路 13(C语言基础学习——预处理命令)

编程流程 在进行程序开发时&#xff0c;通常遵循编辑源代码、编译、运行和调试这几个主要步骤。 编辑源代码&#xff1a;使用文本编辑器创建或修改程序的源代码&#xff0c;这是整个编程过程的起点。编译&#xff1a;将源代码转换为可执行文件的关键步骤。 预处理&#xff1a…