html中script标签使用async属性和defer属性的区别
相同点:
首先async和defer只对header里的外连脚本script标签上起作用,如果script标签是放在header外或者是header里的内置脚本以及动态生成的script标签是不起作用的。其作用是将该js脚本设置为异步加载,主要用于当外链的js文件没有操作DOM的情况。
两者区别:
使用async标志的脚步文件一旦加载完成就会立即执行;使用defer标记的脚本文件会在DOMContentloaded事件之前(也就是页面DOM加载完成时)执行。
如果有多个js脚本文件,async标记不保证按照书写的顺序执行,哪个脚本先下载结束就先执行哪个脚本。而defer标记则会按照js脚本书写顺序执行。
一般来说,如果脚本之间没有依赖关系,就使用async属性,如果脚本之间有依赖关系,就使用defer属性。如果同时使用async和defer属性,后者不起作用,浏览器的行为由async属性决定。
对于async标记,浏览器的解析过程是这样的:
- 浏览器开始解析html网页
- 解析过程中,发现带有async属性的script标签
- 浏览器继续往下解析html网页,同时并行下载script标签中的外部脚本
- 脚本下载完成,浏览器暂停解析html网页,开始执行下载的脚本
- 脚本执行完毕,浏览器恢复解析html网页
对于defer标记,浏览器的解析过程:
- 浏览器开始解析html网页
- 解析过程中,发现带有defer属性的script标签
- 浏览器继续往下解析html网页,同时并行下载script标签中的外部脚本
- 浏览器完成解析html网页,此时再执行下载的脚本
当header中同时有js脚本和外链css时,js脚本最好放外链css前面。因为如果脚本的内容是获取元素的样式,宽高等css控制的属性,浏览器是需要计算的,也就依赖于css。浏览器无法感知脚本内容到底是什么,为避免样式获取错误,因而只好等前面的所有样式下载完后,再执行js。如果css下载时间很长的话,js也无法正常运行,导致html无法正常解析出来,