defer和asnyc(只对外部文件有效)html
defer 在页面完成解析时执行代码,这个属性代表脚本在执行时不会影响页面的构造,在元素中设置这个属性至关于告诉浏览器当即下载但延迟执行segmentfault
async 相对于页面其余部分异步执行脚本,通常的script标签都是会阻塞页面执行的,没有加上async属性的标签会阻塞后面的标签的解析。通常用在不须要操做dom元素的脚本上,例如一些统计代码(跟页面执行逻辑无关的,不涉及dom操做的),能够避免因长时间加载而呈现白屏现象浏览器
script中有或没有它们的区别app
script中没有defer和async,会马上加载并执行dom
script中有async没有defer时,会与渲染后续文档元素并行加载,加载完自动执行异步
script中有defer没有async时,后续文档元素渲染会与脚本文件加载并行,可是执行全部元素解析完成以后,在DOMContentLoaded以前执行async
https://segmentfault.com/q/10... 这个回答很棒性能
可是红宝书中有这样一句话:HTML5规范要求脚本执行应该按照脚本出现的前后顺序执行,但在现实生活中,延迟脚本并不必定按照顺序执行,也不必定会在DOMContentLoaded事件中触发前执行,所以最好只包含一个延迟脚本。所以上图第三点说法有欠缺测试
未解决问题:全部浏览器都兼容,那么为何没有看到别人在用呢?url
查了一下,网易有在用,浏览器兼容仍是有点小问题,and业务需求
script是能够并行下载的,这里应该是指放在head中的script标签,不会阻塞其余script标签,可是仍然会阻塞其余资源下载,例如图片。尽管脚本的下载过程当中不会相互影响,但页面仍然要等到全部js代码下载并完成执行才能继续。-- 《高性能的js》
并行下载测试
建议放在body的底部
每一个script标签初始化都会阻塞页面渲染,在解析html页面过程当中每遇到一个script标签都会因执行脚本而致使必定的延时
尽管单个较大的js文件只请求一次http,可是这样会致使锁死浏览器一段时间,解决方案除了上面所说的defer以外还能够动态建立标签加入head中,能够经过onload事件来监听脚本加载是否完毕,ie下经过readystatechange事件
function loadScript(url, callback) { var script = document.createElement('script'); if ( script.readyState ) { // IE script.onreadystatechange = function(){ if( script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; // 同时检查两种状态,只要有一种触发就删除事件处理器,避免触发两次 callback(); } } }else{ script.onload = function(){ callback(); } } script.src = url; document.getElementsByTagName('head')[0].appendChild(script); }