JS script标签位置、defer、async属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
/**
** 位置1. script 标签在 head 中
** 由于 html 代码是同步按顺序执行的,意味着必须把所有的 script 加载解析执行完成后,再继续渲染页面
** 在多文件时,页面可能出现长白屏时间的问题
**/
<script src="test1.js"></script>
<script src="test2.js"></script>
</head>
<body>
</body>
/**
** 位置2. script 标签在 body 之后
** script 标签中的代码不会阻塞 html 解析,但部分需求可能会遇到部分数据必须在 html 渲染完成前准备完毕,因此此方法也不是万能的
**/
<script src="test1.js"></script>
<script src="test2.js"></script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
/**
** 浏览器解析到 script 标签时,如果标签带有 defer 属性,浏览器会另外开辟一个进程来加载 js 资源,而不会阻塞 html 加载
** 注:带有 defer 属性的 script 资源加载完成后不会立即执行,而是等待 html 渲染完成后执行
**/
<script src="test1.js" defer></script>
<script src="test2.js" defer></script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
/**
** 浏览器解析到 script 标签时,如果标签带有 async 属性,浏览器会另外开辟一个进程来加载 js 资源
** 资源加载完成后会暂停 html 渲染,并执行 script 脚本
**/
<script src="test1.js" async></script>
<script src="test2.js" async></script>
</head>
<body>
</body>
</html>
注:① defer 和 async 脚本只适用于外部脚本,都会立即并行加载 script 资源,不同的是,defer 将 script 脚本的运行放到了最后,而 async 则是加载完后立即暂停 html 渲染,等待 script 执行完成后再继续。
② 多个带有 defer 或 async 的 script 标签,由于每个 script 标签的加载都是单独另外开辟的进程,位置靠后的 script 资源可能先于完成,因此无法保证每个标签是按照代码位置顺序执行的,