本文详解JavaScript中async与defer属性的应用场景及区别。针对需在JS中获取DOM节点的场景,通过对比常规加载、async与defer的执行顺序,说明如何避免null值错误。重点解析async基于下载完成的异步执行与defer基于文档解析完成的有序执行机制,帮助开发者优化页面渲染性能。
async与defer的应用场景
async与defer属性的应用场景
在某些特定场景下,例如需要确保DOM元素更新完毕后才能执行JavaScript代码,但由于JavaScript是单线程机制,脚本加载和解析需要耗费时间,导致脚本执行时DOM尚未就绪。若此时脚本试图获取DOM节点信息,可能会失败。为解决这一问题,可以使用async或defer属性来优化脚本加载时机。
通常,为了减少浏览器渲染阻塞,建议将script标签放置在</body>标签之前,以避免JavaScript的加载和执行占用HTML渲染时间。以下示例仅用于演示原理。
具体示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script src="./index.js"></script>
<body>
<div id="box"></div>
</body>
</html>
index.js文件内容
const box = document.getElementById("box");
console.log(box);
由于JavaScript默认从上到下顺序执行,若脚本在DOM解析完成前执行,此时尝试获取div节点将返回null,因为该元素尚未被创建。

通过引入async或defer属性,可以确保脚本在DOM信息可用时执行,从而成功获取DOM节点。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
// 或者这里写 defer
<script async src="./index.js"></script>
<body>
<div id="box"></div>
</body>
</html>此时即可正确获取到节点信息。

defer与async的执行机制对比
defer与async的核心区别

defer属性:脚本会等待HTML文档解析完成后,按照在文档中出现的顺序依次执行。
async属性:脚本与HTML解析并行进行,一旦脚本下载完成即执行,不保证执行顺序,先完成的脚本先执行。
async的执行流程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
// 这里的执行顺序 是谁先完成就谁先执行
<script async src="./index1.js"></script>
<script async src="./index2.js"></script>
<script async src="./index3.js"></script>
<body>
<div id="box"></div>
</body>
</html>defer的执行流程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
// defer 是从上到下依次执行的
<script defer src="./index1.js"></script>
<script defer src="./index2.js"></script>
<script defer src="./index3.js"></script>
<body>
<div id="box"></div>
</body>
</html>本文介绍了JavaScript中async与defer的应用及区别,更多相关延迟加载内容可参考本站其他文章。