script标签defer和async属性的区别

如题所述

第1个回答  2022-07-10
为了提高页面加载性能,在页面引入外部js的时候,可以使用script标签的 defer 和 async 属性来使得外部js异步加载
script标签的使用分为三种情况:

没有defer或async属性,浏览器会立即加载并执行相应的脚本。也就是说在渲染script标签之后的文档之前,不等待后续加载的文档元素,读到就开始加载和执行,此举会阻塞后续文档的加载;

有了async属性,表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的,即异步执行;

有了defer属性,加载后续文档的过程和js脚本的加载(此时仅加载不执行)是并行进行的(异步),js脚本的执行需要等到文档所有元素解析完成之后,DOMContentLoaded事件触发执行之前。

下图可以直观的看出三者之间的区别:

其中蓝色代表js脚本网络加载时间,红色代表js脚本执行时间,绿色代表html解析。

从图中我们可以明确几点:

小结:
defer 和 async 的共同点是都是可以并行加载JS文件,不会阻塞页面的加载,不同点是 defer的加载完成之后,JS会等待整个页面全部加载完成了再执行,而async是加载完成之后,会马上执行JS,所以假如对JS的执行有严格顺序的话,那么建议用 defer加载。

参考: use_async_or_defer
In general, you should always use async or defer for third party scripts (unless the script does something necessary for the critical rendering path):

Should you ever load third-party scripts without async or defer? You could make a case for this if the script is a crucial part of your site functionality. For example, if you're loading your main UI library or framework from a CDN, it will be badged as "third-party script" in DevTools, but should be treated as an essential part of your site, not an add-on.

Note that not all scripts work if loaded asynchronously. Check the docs for any third-party scripts you're using. If you're using a script that can't be loaded asynchronously, you might want to consider an alternative, or eliminating the script if possible. Some third parties may highly recommend to load their scripts sync (to get ahead of other scripts), even if they would work fine async so do due diligence when evaluating strategies for loading third-party scripts.