Q1:script标签的defer,async的区别
这两个元素在红包书的第二章中就有介绍,先看下来自书中的定义:
async:可选,表示应该立即下载脚本,不妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本。只对外部脚本有效。
defer:可选,表示脚本可以延迟到文档完全被解析和显示之后再执行,只对外文脚本有效。
了解了定义后。
解释一下就是defer和async都会让脚本异步加载,但是defer加载完脚本并不立即执行,而是等待后续文档渲染加载完毕后执行。ascync则是加载脚本立刻执行,在执行js脚本时会阻塞dom的渲染。
最后回到这个问题,总结derfer,async的区别:
是否异步 | 是否阻塞dom渲染 | |
---|---|---|
async | 是 | 是,async异步加载文档后立即执行,这时会阻塞dom渲染 |
defer | 是 | 否,待文档全部渲染完后才执行脚本。( script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成) |
此图告诉我们以下几个要点:
1、defer 和 async 在网络读取(下载)这块儿是一样的,都是异步的(相较于 HTML 解析)
它俩的差别在于脚本下载完之后何时执行
2、显然 defer 是最接近我们对于应用脚本加载和执行的要求的
3、关于 defer,此图未尽之处在于它是按照加载顺序执行脚本的,这一点要善加利用
4、async 则是一个乱序执行的主,反正对它来说脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行
5、仔细想想,async 对于应用脚本的用处不大,因为它完全不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的,最典型的例子:Google Analytics
当然,我们在开发中想要避免加载脚本阻塞页面渲染带来的白屏等性能问题,最稳妥的方式还是把script引入的外部脚本丢在html结构的尾部,避免了兼容问题,以及async存在的执行顺序问题。