preload与defer脚本执行顺序疑问:为何defer脚本先于preload回调执行?
问题解析:preload onload 晚于 defer 脚本执行的原因
先看你给出的代码:
HTML 代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>preload and prefetch</title> <link rel="preload" href="./a.js" as="script" onload="console.log('a.js loaded')"> </head> <body> </body> <script src="./a.js" defer></script> </html>
JS 代码(a.js)
// a.js console.log("a");
核心原因
你误解了preload的作用:preload只是提前请求并缓存资源,它不会控制资源的执行时机,也不会让脚本等待preload完成后再执行。
具体到你的场景:
preload标签会第一时间发起a.js的下载请求,但它仅仅是把资源缓存到浏览器,不会执行这个脚本。- 后面的
<script defer>标签请求同一个资源时,浏览器会复用preload的下载请求,避免重复下载。 defer脚本的执行规则是:等整个HTML文档解析完成后,再按脚本在文档中的顺序执行。由于你的HTML内容极少,解析几乎瞬间完成,所以当a.js下载完成后,浏览器会立刻执行这个defer脚本。- 而preload的
onload回调是在资源下载完成时触发的事件,它属于浏览器的宏任务队列。在事件循环的处理顺序中,defer脚本的执行优先级高于普通事件回调,所以console.log('a')会先于console.log('a.js loaded')输出。
简单说:preload只负责"提前下载",脚本什么时候执行完全由<script>标签的属性(这里是defer)决定,preload的onload和脚本执行之间没有强制的先后顺序,只是当前场景下defer脚本先被处理了。
内容的提问来源于stack exchange,提问作者Lee KimSohyun
相关产品推荐
相关产品推荐

