<script>元素的 defer和async属性

290 阅读2分钟

对于一些概念性的东西总是不容易记住,今天又在无意间看到deferasync,回忆起来总感觉还是很熟悉,讲起来又感觉很生涩...所以,索性重新认识一下它们,以便加深一点印象。翻开《JavaScript高级程序设计》对它俩的定义

defer延迟脚本

defer: HTML 4.01O <script>标签定义了defer属性,这个属性的用途是表明脚本在执行时不会影响页面的构造。也就是说,脚本会被延迟到整个页面都解析完毕后再运行。因此,在<script>元素中设置defer属性,相当于告诉浏览器立即下载,但延迟执行。

写个demo的执行过程:

打印顺序如下:

由此可见:文件依然是按顺序加载,但是加了defer的文件defer2.js在最后执行。

defer属性只适用于外部脚本文件

也就是只有script,src引入的脚本才能有延迟效果。

顺序执行?

上图执行顺序中可以看出,延迟脚本在最后执行,但是会先于DOMContentLoaded事件触发前执行。然而,红宝书还是留下了一句充满悬念的话:

在现实当中,延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoaded事件触发前执行,因此最好只包含一个延迟脚本。

到底什么场景下会不按顺序执行呢?又是什么场景下不会在DOMContentLoaded事件触发前执行?求哪位大神解答一下呀!

async异步脚本

HTML5为<script>元素定义了async属性。这个属性与defer属性类似,都用于改变处理脚本的行为。同样与defer类似,async只适用于外部脚本文件,并告诉浏览器立即下载文件。但与defer不同的是,标记为async的脚本并不保证按照指定它们的先后顺序执行。

defer和async的区别

从定义可见:

  • 首先,两者都只对外部脚本有效;
  • 两者都是异步,执行时不会影响页面的构造和其他操作;
  • defer加载完后会延迟执行;
  • async加载完后便会立即执行,且是乱序执行的,谁先加载完谁就会先执行,不适合做依赖脚本的场景,但对于不存在依赖的情况下倒是挺合适的,比如:百度统计之类的...