script 标签用于加载脚本与执行脚本,在前端开发中可以说是非常重要的标签了。
直接使用 script 脚本的话, html 会按照顺序来加载并执行脚本,在脚本加载&执行的过程中,会阻塞后续的 DOM 渲染。现在大家习惯于在页面中引用各种的第三方脚本,如果第三方服务商出现了一些小问题,比如延迟之类的,就会使得页面白屏。
好在 script 提供了两种方式来解决上述问题, async 和 defer ,这两个属性使得 script 都不会阻塞 DOM 的渲染。
但既然会存在两个属性,那么就说明,这两个属性之间肯定是有差异的。defer
如果 script 标签设置了该属性,则浏览器会异步的下载该文件并且不会影响到后续 DOM 的渲染;
如果有多个设置了 defer 的 script 标签存在,则会按照顺序执行所有的 script ;
defer 脚本会在文档渲染完毕后, DOMContentLoaded 事件调用前执行。我们做了一个测试页面,页面中包含了两个 script 标签的加载,给他们都加上 defer 标识。
P.S. 为了更直观,我们给 script1.js 添加了 1s 的延迟,给 script2.js 添加了 2s 的延迟。
下图是页面加载的过程& script 脚本的 输出顺序。
不难看出,虽然 script1 加载用时虽然比 script2 短,但因为 defer 的限制,所以Ta只能等前边的脚本执行完毕后才能执行。
async
async 的设置,会使得 script 脚本异步的加载并在允许的情况下执行
async 的执行,并不会按着 script 在页面中的顺序来执行,而是谁先加载完谁执行。我们修改测试页面如下:
遂得到了如下的结果,页面加载时长上,并没有什么变化,毕竟都是异步加载的脚本。
但是我们可以看到一个小细节, DOMContentLoaded 事件的触发并不受 async 脚本加载的影响 ,在脚本加载完之前,就已经触发了 DOMContentLoaded 。
我们接着修改测试页面。加载一个没有延迟的 script 脚本,使得脚本可以即时的加载完毕。
我们要测试一下,如果 async 脚本加载的足够快,是否会在 DOMContentLoaded 之前就执行( 这个实验是基于对 async 的描述“在允许的情况下执行”的论证 )。
同时为了保证测试的稳定性,我们在 script 脚本引入的后边添加了数千个空的 p 节点,用来延长文档的渲染时间。
执行结果不出所料,如果给 async 一定的时间,是有可能在 DOMContentLoaded 事件之前就执行的。
P.S. 从上图中左上角的火焰图中,我们也能看到,出现了多段的 蓝色 (更新:晚上写的时候懵了,紫色的才是渲染,蓝色的是解析)文档渲染。以及下边 Console 的顺序。
说明的确, async 的执行是加载完成就会去执行,而不像 defer 那样要等待所有的脚本加载完后按照顺序执行。画几张图简要说明
网上有了不少这种类似的图,但是基本都是拿一个script就举例的
未免太过寒酸,so咱们来一个豪华版,来画一下多个脚本加载时的甘特图
就像近年来各大手机厂商,出新机都喜欢来一个X+X plus拿四个不同的颜色来标明各自代表的含义
普通script
文档解析的过程中,如果遇到 script 脚本,就会停止页面的渲染进行下载(但是并不会影响后续的解析,解析和渲染是两码事儿)。
资源的下载是在解析过程中进行的,虽说 script1 脚本会很快的加载完毕,但是他前边的 script2 并没有加载&执行,所以他只能处于一个挂起的状态,等待 script2 执行完毕后再执行。
当这两个脚本都执行完毕后,才会继续渲染页面。
defer
文档解析时,遇到设置了 defer 的脚本,就会在后台进行下载,但是并不会阻止文档的渲染,当页面解析&渲染完毕后。
会等到所有的 defer 脚本加载完毕并按照顺序执行,执行完毕后会触发 DOMContentLoaded 事件。
async
async 脚本会在加载完毕后执行。
async 脚本的加载不计入 DOMContentLoaded 事件统计,也就是说下图两种情况都是有可能发生的
推荐的应用场景
defer
如果你的脚本代码依赖于页面中的 DOM 元素(文档是否渲染完毕),或者被其他脚本文件依赖。
例:评论框
代码语法高亮
polyfill.js
async
如果你的脚本并不关心页面中的 DOM 元素(文档是否渲染完毕),并且也不会产生其他脚本需要的数据
以上就是script标签中的async和defer用法的详细内容,更多请关注Gxl网其它相关文章!
查看更多关于script标签中的async和defer用法的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did72060
script标签中的async和defer用法
阅读:34次