HTML – script async defer

参考

Youtube – #3 JavaScript Loading Strategies (async and defer) | JavaScript Full Tutorial

 

no async no defer

当游览器 parse HTML 遇到 <script src> 时, 它会去 download 这个 file, 这时会停止 parse HTML. 一直等到这个 JS file download 完毕.

然后游览器会开始 execute 这个 JS file 代码. executed 后继续 parse HTML.

parse HTML > download js > waiting download completed > execute js > continue parse HTML

 

async

async 是异步 download, 当游览器 download JS file 时, 它不会等, 而是继续 parse HTML.

等到这个 file download 完毕, 就暂停 parse HTML, 去 execute JS file. executed 后继续 parse HTML.

有一点需要特别注意, 如果有多个 async file, 游览器不会管它们的顺序, 哪个先 download 完毕就马上 execute.

parse HTML > download a.js (no waiting) > parse HTML > download b.js (no waiting) > parse HTML > 

b.js finish download > execute b.js > parse HTML > a.js finish download > execute.a.js > parse HTML

 

defer

defer 也是异步 download, 但它 download 完毕之后并不会马上 execute. 而是等到 parse HTML 结束后才 execute.

而已它 execute 是讲究顺序的.

parse HTML > download a.js (no waiting) > parse HTML > download b.js (no waiting) > parse HTML > 

b.js finish download (no run first) > parse HTML > a.js finish download (no run first) > parse HTML finish > execute.a.js (依据顺序) > execute b.js.

 

async defer together?

看到 facebook 的 sample code 是 2 给一起用. 于是查了一下

stackoverflow – Can you use both the async and defer attributes on a HTML script tag?

原来是为了兼容游览器, 有些游览器不支持 async. 注意是当你想 async 的时候但怕不支持所以才加上 defer. 而不是反过来哦. 

async 如果运行的到, 那么 defer 就被无视了.

 

关于 DOMContentLoaded

参考: 详解 DOMContentLoaded

HTML parse 完以后, DomContentLoaded 会等到所有 defer download 完同时 execute 完以后才触发.

但是它不会去等待 async. HTML parse 完, 如果还有 async 没用在 download, 它不管, 会直接去触发 DomContentLoaded.

 

总结:

1. 以前需要把 JS 写到 body 最后面, 现在被 async defer 取代了.

2. async defer 用其中一个就可以了.

3. defer 是最常用的, 因为通常在乎顺序

4. async 的一个使用场景是 analytics 因为希望尽快做 tracking, defer 有点慢了.

 

Chrome Bug ? JS run before CSS render when using defer + compression

23-04-2022 遇到一个奇葩情况.

JavaScript 执行的比 CSS download file 还早. 这导致 computedStyle 获取到错误的值

它需要几个情况一起才会发生.

1. Chrome version 100.0.4896.127

2. script with defer

3. script with compression (br)

做了一个 ASP.NET Core 的测试环境

开启 compression, 当 download CSS 时刻意让它慢

HTML

Javascript 执行就 log

用 Firefox 测试效果是, 5 秒后 log

用 Chorme 是马上 log.

如果关闭 compression 效果则 Firefox 和 Chrome 都是 5 秒后 log.

如果把 defer 拿掉, 同时把 script 移动到 </body> 前, Firefox 和 Chrome 都是 5 秒后 log.

结论就是 Chrome + defer + compression 会导致 log 提前执行 (哪怕你放到 </body> 前). 

所以建议暂时不要使用 defer, 改成把 script 放到 </body> 前.

 

posted @ 2022-03-18 21:04  兴杰  阅读(82)  评论(0编辑  收藏  举报