将 script 放在尾部的缺点,是浏览器只能先解析完整个 html 页面,再下载 JS。而对于一些高度依赖于 JS 的网页,就会显得慢了。所以将 script 放在尾部也不是最优解,最优解是一边解析页面,一边下载 JS。
因为在 body 以外写 script 也可能存在其他异常嘛。有什么理由能让开发者推断出后者会更安全呢?实际上在没有充分测试的前提下,如果要进行推断,那么可以推断出后者的风险更大。
第一,这是不合标准的行为,而且从有 HTML 标准以来都是不合标准的,因此浏览器实现不一致或者在这种情况下有 bug 的风险显然更大。
第二,虽然将 <script> 写在 </body> 之后,但最终的 DOM 树里,<script> 元素还是会成为 body 的子节点,这一点很容易在 firebug 等调试器里验证。既然如此,如果将 <script> 写在 </body> 之前会有问题,你又如何保证写在之后(并在 DOM 里又变成了和写在之前一样的结构)就没有问题?
那最优解的一边解析页面一边下载 JS 应该怎样实现呢?
我们 <script> 标签这里面有两个属性(async 和 defer),现在 80% 的浏览器都可以识别他们,这两个属性能让浏览器做到一边下载 JS(还是只能同时下载两个 JS),一边解析 HTML。他的优点不是增加 JS 的并发下载数量,而是做到下载时不 block 解析 HTML。
- 1 <script type="text/javascript" src="path/to/script1.js" async></script>
- 2 <script type="text/javascript" src="path/to/script2.js" async></script>
如上图我们同时引入两条外部 js 文件时:
async 属性能保证 script 会异步执行,只要下载完就执行,这会导致 script2.js 可能先于 script1.js 执行(如果 script2.js 比较大,下载慢)。
defer 属性就能保证 script 有序执行,script1.js 先执行,script2.js 后执行。
来源: