因为JavaScript具有两个特性:
- JavaScript会阻塞后面内容的呈现
- JavaScript会阻塞其后组件的下载
因此为了能保证最基本的浏览需求,所以有时候会考虑到异步加载。
利用 async
或者defer
异步延迟加载脚本
如果没有async
或者defer
,浏览器在读取到JavaScript时会立即加载并执行指定的脚本。但是,JavaScript是对文档的元素进行操作,如果没有解析Html直接加载JavaScript,有可能会出现报错。
用法:
async:相对于页面的其他部分异步执行。作用是不让页面等待两个或两个以上的脚本下载和执行,从而异步加载页面的其他内容。
<!DOCTYPE html>
<head>
<title>title</title>
<script type="text/javascript" async src="a.js"></script>
<script type="text/javascript" async src="b.js"></script>
</head>
<body>
<!-- 内容 -->
</body>
</html>
因为async
属性是HTML5新增属性,需要Chrome、FireFox、IE9+浏览器支持,并且不保证加载顺序。
defer:延迟到整个页面都解析完毕后在执行。
<!DOCTYPE html>
<head>
<title>title</title>
<script type="text/javascript" defer src="a.js"></script>
<script type="text/javascript" defer src="b.js"></script>
</head>
<body>
<!-- 内容 -->
</body>
</html>
兼容所有浏览器。理论上确保所有设置了defer
属性的脚本按顺序执行。
共同点:
- 设置了
async
或者defer
属性的脚本不会阻塞页面渲染 -
async
和defer
属性决定了js脚本的执行方式,内联脚本会忽略这两个属性。仅针对外部脚本起作用 - 使用这两个属性的脚本中不能调用
document.write
区别:
异步脚本一定会在页面的load
事件前执行,但可能在DOMContentLoaded
事件触发之前或之后执行,所以可能出现无序加载js的情况;延迟脚本在文档完成解析后,执行理论上是有序的,但现实中并不能保证顺序,也不一定会在DOMContentLoaded
事件触发前执行。