一起了解script标签中的async和defer属性

一、什么是script标签

在网页开发中,我们常常使用script标签来引用Javascript脚本文件。Script标签可以直接嵌入JS代码,也可以通过src属性引入外部JS文件。以下是两者的示例。

//内部嵌入JS代码

<script>

alert("Hello World");

</script>

//外部引入JS文件

<script src="filename.js"></script>

二、为什么要使用async和defer属性

1. 防止JS阻止页面加载

由于浏览器是单线程处理页面,因此如果在页面加载时遇到script标签(尤其是外部脚本文件),它就需要停止页面的渲染,加载并执行JS脚本,然后才能继续绘制页面。当JS文件较大或网络较慢时,会使得页面加载变得缓慢,影响用户的体验。此时就需要使用async或defer属性来避免这种情况的发生。

2. 延迟JS执行时间

有时候,我们并不希望JS脚本在页面完全加载后立即执行,而是希望它在仅在DOM完全解析后再执行。使用defer属性可以实现这一目的。此外,使用defer属性也可以让多个脚本按照顺序依次执行,避免脚本之间的依赖关系错误导致问题。

三、async和defer的区别

1. async属性

async属性是HTML5中新增的属性,它表示异步加载JS文件,即不会阻塞页面的渲染,立即进行下载,下载完成后会执行JS脚本文件。注意,由于JS文件是异步加载的,因此如果有多个JS文件在一起使用async属性引入,它们的执行顺序是不可控的。

2. defer属性

defer属性也是HTML5中新增的属性,它表示延迟执行JS文件,即在页面完全加载完成后执行JS脚本文件,此时JS文件是按照顺序加载并依次执行。另外,defer属性仅对外部脚本文件有效。

四、应该如何选择

在选择async和defer属性时,需要根据实际情况进行决策。一般来说,如果JS文件之间的执行顺序不影响脚本的正确性和展示效果,可以使用async属性;如果JS文件之间有依赖关系,或需要在DOM完全加载后执行,建议使用defer属性。

下面是一个例子,展示了defer和async属性的不同效果。代码如下:

//defer

<script defer src="filename1.js"></script>

<script defer src="filename2.js"></script>

//async

<script async src="filename1.js"></script>

<script async src="filename2.js"></script>

使用defer属性时,文件1和文件2的执行顺序是有保证的,同时它们都会在DOM解析完成后执行。如下图所示:

然而,使用async属性时,文件1和文件2的执行顺序是不确定的,可能会出现文件2在文件1之前执行的情况。如下图展示:

五、总结

在开发网页时,script标签是不可缺少的。但是,由于JS脚本的执行可能会导致页面加载变慢,我们推荐在使用外部JS文件时,使用async或defer属性可以提高页面的渲染速度和执行效率。在使用二者时,应该根据实际情况进行选择,建议在使用多个JS文件时,使用defer属性,以保证它们的执行顺序和正确性。