script 中什么情况下使用async 的 defer

新手上路,请多包涵

突然看到script中出现 async defer属性,不太理解,阅读了大量网上解析后,不知道怎么回事,之前感觉理解清楚了,现在我突然糊涂了(可能是没有休息好,此处是借口),不知道什么情况下使用async 和 defer 是最优的,请大神们给我一个通俗的解释.越俗越好.

以下是我理解的过程
阅读文档后我大概得到了以下的理解
async:仅适用于外链,下载时不会阻塞页面链接,脚本加载后立即执行,执行时阻塞html解析,不会按顺序执行那个完成就执行哪一个.执行的时候有可能页面没有加载完成.
defer:仅适用于外链,规定脚本延迟执行,不会阻塞页面解析,在 HTML 解析完成后,DOMContentLoaded 之前执行,按照出现的顺序执行.

得到以上理解之后看了一篇文章https://segmentfault.com/a/1190000006778717
这篇文章最后的结论是

其实这么讲来,最稳妥的办法还是把<script>写在<body>底部,没有兼容性问题,没有白屏问题,没有执行顺序问题,高枕无忧,不要搞什么deferasync的花啦~

在这片文章的评论中:
给出了使用async和defer的好处:节省时间

将js放在头部,用defer或async异步加载。相比js放到底部什么都不加。不是省了下载文件的时间嘛

那问题来了,在优化的情况下,
问题一:我想使用async和defer,什么时候使用async defer不会出现兼容,白屏等问题,
问题二:或者说在出现兼容,白屏等问题,在优化的情况下有没有解决方案

阅读 4.7k
4 个回答
  1. 这些 JS 都应该放在页面最后,无论加不加 deferasync
  2. 页面强逻辑——即没有这个逻辑你的页面就没法工作——不需要加
  3. 独立功能的 JS,比如 GA 统计,适合用 async,因为它是独立的,加载完就执行
  4. 同样是独立功能,但是多个 JS 彼此之间有关联,用 defer,因为会按照它们在页面中的顺序执行
  5. 因为 defer 的 JS 在执行完毕前会阻止浏览器触发 DOMContentLoaded 事件,所以在比较老的页面里(通常依赖 jQuery 的 $(function () {}) )要慎用

在服务器端配置好http 2.0,从此不必再学这些没用的优化技巧了。

摘抄自《JavaScript高级程序设计》
<script>标签的defer属性

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

<script> 标签的 async 属性

async属性与defer属性类似,都用于改变处理脚本的行为,async只适用于外部脚本文件,并告诉浏览器立即下载文件。但与defer不同的是,标记为async的脚本并不保证按照指定它们的先后顺序执行。指定async属性的目的是不让页面等待脚本下载和执行,从而异步加载页面其他内容。为此,建议异步脚本不要在加载期间修改DOM。

我的理解是,不论 asyncdefer,JS都要先加载再执行,如果引用的一堆js文件都是可用的、极速加载的,那么放在 head</body>都一样,不存在用户对页面体验的影响,中间经历的同步异步阻不阻塞也感觉不到,反正没有出错,一瞬间就完成了。

现在要讨论的是引用的这一堆js是不是可用的和极速加载的问题,如果js是不可用的,那么放在页头还是页尾,页面都会“转圈”,直到超时,体验都会不好;区别是放在页头,“白屏”时间更长;如果js是可用但加载缓慢的,放在页头的话,一是加载时会占用时间,二是执行会形成阻塞,都会延长“白屏”时间,所以放在页尾就比较合适了,至少html等内容都加载和渲染差不多了,页面上有内容了。

异步加载的都是外部文件,而且只是下载异步,执行的时候同样会阻塞,只是阻塞的时间延后了。如果把页面的js代码放在外部文件下面,或者在 DOMContentLoaded 事件之前执行,那同样会阻塞。

那么把JS都放在页尾的话,还有必要异步么?这就要看加载的一堆JS里是否有依赖和加载的顺序了,异步又是乱序的(谁先加载谁执行,同步是有顺序的),也会产生一定的副作用。

我的结论是:JS优先放在页尾,一定要放在页头的JS可异步。依赖文件可同步(先加载),需要依赖和修改DOM的文件异步加载(最后执行)。


重点是先保证外部文件可用且加载速度快。没做过大项目,异不异步的也没感觉到差异。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏