网页控制script脚本异步执行方案,async和defer属性异同
发布于 作者:苏南大叔 来源:程序如此灵动~在上一篇文章中,苏南大叔描述了网页使用script
标签的defer
属性的问题,defer
的作用是把一些脚本延迟到最后再执行。这对于网页元素加载来说,就是异步加载了。但是,script
标签还有另外一个async
属性,这个async
属性可是货真价实的“异步加载”的意思。那么,这个属性又怎么使用呢?和defer
属性,又有什么区别呢?这些就是本文要讨论的问题。
大家好,这里是苏南大叔的“程序如此灵动”博客,这里讲述苏南大叔和计算机代码的故事。本文讲述script
标签的async
属性,语义上来说,async
是用来异步加载的。那么,它的使用方式是怎么样的呢?
本文测试环境:win10
,chrome@100.0.4896.60
。
测试代码
本篇文章里面的测试代码,是基于defer
的文章测试代码,可以先考虑前一篇文章的内容:
测试方式是通过浏览器访问web,并不是双击.html
文件。
这里测试以下几种代码:
<script type="module" src="./1.js"></script>
<script type="module" async src="./2.js"></script>
<script type="module">
import aa from './3.js'
</script>
<script type="module" async>
import aa from './4.js'
</script>
<script async src="./5.js"></script>
<script src="./6.js"></script>
<script async>
console.log("7.js");
</script>
<script>
console.log("8.js");
</script>
其中3.js
和4.js
都export
了一个空函数。
console.log("3.js");
export default ()=>{};
测试结果
这里先说基本原则:
async
的意思是异步执行,被设置async
的代码,在效果上会移动到页尾加载执行,完全忽视其在页面中的物理位置。type="module"
的script
,直接默认就是async
的。加不加async
都是async
。- 内联的
script
(就是把逻辑写在html
页面里面的,不是保存为一个文件的),默认都不是async
的。加不加async
都不是async
。
然后苏南大叔在所有的被测试js
前面,再加个内联的onload
:
<script>
window.addEventListener('DOMContentLoaded', function () {
console.log('DOMContentLoaded')
})
</script>
然后,这8种js
,以及这个DOMContentLoaded
,到底谁先谁后呢?
结论是这样的:非async
的最先执行,而async
的则在页面后面随机执行,甚至会出现比DOMContentLoaded
更后执行。
可能是4.js
里面需要compile
的代码更多一些,所以在最后执行了。
特殊情况
在设置了async
的.js
里面,使用document.write
语句的话。会得到警告信息,并且不会正确输出.write
信息。
Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.
defer
和async
属性应用场景
名称 | 说明 |
---|---|
defer | 多个script ,相互之间有依赖关系的话,就可以设置defer 属性。这样能完整的保持执行顺序。 |
async | async 属性的script ,因为其执行顺序不能保证。所以,对应的模块必须要独立使用,彼此之间没有依赖关系。 |
比如百度统计代码,实际上就不应该按照官方推荐放置到页面顶部,而是应该放置到页面底部,并且加上async
属性。当然,如果您还是不明白到底该使用那个属性,那么,defer
是最好的选择。
参考文献
综述
本文讲述了script
的async
属性,它可以把一些js
移动到后面执行,以免阻碍页面渲染。更多js
文章,可以点击:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。