async与defer的区别

script执行

浏览器在执行HTML的时候如果遇到<script>时会停止页面的渲染,去下载和执行js的文件直接遇见</scirpt>会继续渲染页面。故浏览器在执行js文件的时候浏览器表现为一片空白,为了解决这个问题ECMAScript定义了defer和async两个属性用于控制JS的下载和执行

async是在HTML5中加入的

defer

defer

对于defer,我们可以认为是将外链的js放在了页面底部。js的加载不会阻塞页面的渲染和资源的加载。不过defer会按照原本的js的顺序执行,所以如果前后有依赖关系的js可以放心使用

async

async

和defer一样,会等待的资源不会阻塞其余资源的加载,也不会影响页面的加载。但是有一点需要注意下,在有async的情况下,js一旦下载好了就会执行,所以很有可能不是按照原本的顺序来执行的。如果js前后有依赖性,用async,就很有可能出错。

区别

相同点:

  • 加载文件时不阻塞页面渲染
  • 对于inline的script无效
  • 使用这两个属性的脚本中不能调用document.write方法
  • 有脚本的onload的事件回调

区别点:

  • html4.0中定义了defer;html5.0中定义了async
  • 浏览器支持不同
  • 每一个async属性的脚本都在它下载结束之后立刻执行,同时会在window的load事件之前执行。所以就有可能出现脚本执行顺序被打乱的情况;每一个defer属性的脚本都是在页面解析完毕之后,按照原本的顺序执行,同时会在document的DOMContentLoaded之前执行。

简单的来说,使用这两个属性会有三种可能的情况

  • 如果async为true,那么脚本在下载完成后异步执行。
  • 如果async为false,defer为true,那么脚本会在页面解析完毕之后执行。
  • 如果async和defer都为false,那么脚本会在页面解析中,停止页面解析,立刻下载并且执行

无论使用defer还是async属性,都需要首先将页面中的js文件进行整理,哪些文件之间有依赖性,哪些文件可以延迟加载等等,做好js代码的合并和拆分,然后再根据页面需要使用这两个属性

疑惑

在《JavaScript高级程序设计》的P13中提到

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

原文如下:

In reality, though, deferred scriptsdon’t always execute in order or before the DOMContentLoaded event, so it’s best to include just onewhen possible.

那么什么情况下defer会不按照顺序执行

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 简单介绍JavaScript的发展历史 JavaScript因互联网而生,回顾它的历史要从浏览器的历史讲起。 19...
    _Dot912阅读 3,570评论 0 3
  • 没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下...
    饥人谷_Shirley阅读 4,520评论 0 0
  • defer和async是script标签的两个属性,用于在不阻塞页面文档解析的前提下,控制脚本的下载和执行。我们先...
    曾祥辉阅读 10,514评论 0 2
  • 本文总结一下浏览器在 javascript 的加载方式。关键词:异步加载(async loading),延迟加载(...
    4ea0af17fd67阅读 4,692评论 0 2
  • 浏览器中script标签加载顺序是如何的呢?这个问题折腾了好几次了,之前弄清楚了以后,觉得做不做笔记的无关紧要,可...
    世事如烟_f411阅读 5,531评论 0 1

友情链接更多精彩内容