-
defer和asnyc(只对外部文件有效)
defer 在页面完成解析时执行代码,这个属性表明脚本在执行时不会影响页面的构造,在元素中设置这个属性相当于告诉浏览器立即下载但延迟执行
async 相对于页面其他部分异步执行脚本,一般的script标签都是会阻塞页面执行的,没有加上async属性的标签会阻塞后面的标签的解析。一般用在不需要操作dom元素的脚本上,例如一些统计代码(跟页面执行逻辑无关的,不涉及dom操作的),可以避免因长时间加载而呈现白屏现象
-
script中有或没有它们的区别
script中没有defer和async,会立刻加载并执行
script中有async没有defer时,会与渲染后续文档元素并行加载,加载完自动执行
script中有defer没有async时,后续文档元素渲染会与脚本文件加载并行,但是执行所有元素解析完成之后,在DOMContentLoaded之前执行
https://segmentfault.com/q/10... 这个回答很棒
但是红宝书中有这样一句话:HTML5规范要求脚本执行应该按照脚本出现的先后顺序执行,但在现实生活中,延迟脚本并不一定按照顺序执行,也不一定会在DOMContentLoaded事件中触发前执行,因此最好只包含一个延迟脚本。因此上图第三点说法有欠缺
未解决问题:所有浏览器都兼容,那么为什么没有看到别人在用呢?
查了一下,网易有在用,浏览器兼容还是有点小问题,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);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。