环境:
- chrome31/firefox25/IE11(其它版本没有测试),下列简称chrome/firefox/IE
- http://127.0.0.1:8081/test一、http://127.0.0.1:8081/test2和http://127.0.0.1:8081/test3分别延迟5秒、3秒和当即,并会在控制台里打印test一、test2和test3
测试代码:
HTML:javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>script async defer</title>
<script type="text/javascript">
window.onload = function() {
console.log('onload');
}
document.addEventListener('DOMContentLoaded', function() {
console.log('DOMContentLoaded');
});
</script>
<script type="text/javascript" src="http://127.0.0.1:8081/test1"></script>
<script type="text/javascript" src="http://127.0.0.1:8081/test2"></script>
<script type="text/javascript" src="http://127.0.0.1:8081/test3"></script>
</head>
<body>
</body>
nodejs作server:html
var http = require('http');
http.createServer(function(req, res) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
if (req.url == '/test1') {
setTimeout(function() {
res.end("console.log('test1');");
}, 1000 * 5);
} else if (req.url == '/test2') {
setTimeout(function() {
res.end("console.log('test2');");
}, 1000 * 3);
} else {
res.end("console.log('test3');");
}
// res.end('Hello World\n');
}).listen(8081, '127.0.0.1');
console.log('Server running at http://127.0.0.1:8081/');
测试步骤:
- 不为script设定defer或async时
- 页面会在全部script加载和执行完后渲染 ,输出test一、test2和test3,DOMContentLoaded,onload
设置deferjava
- test1为defer ,chrome/IE会等test2的3秒延迟后,控制台会当即输出test2和test3,等test1的5秒后会输出test1并触发DOMContentLoaded,最后触发onload;firefox会等test2的3秒延迟后,控制台会当即输出test2和test3并触发DOMContentLoaded,等test1的5秒后会输出test1,最后触发onload;
- test1和test2都为defer时,chrome/IE会当即输出test3,尽管test2比test1先加载完成可是只有等到test1加载完成执行后才继续执行,输出为test1和test2并触发DOMContentLoaded,最后触发onload;firefox会当即输出test3并触发DOMContentLoaded,test2下载完后等test1下载完并执行后才执行,输出test1和test2,最后触发onload
设置asyncnode
- test1为async ,等test2的3秒延迟后,会当即输出test2和test3并触发DOMContentLoaded,等test1的5秒后会打印test1,最后触发onload
- test1和test2都为async时 ,会当即输出test3并触发DOMContentLoaded,test2先加载完先打印test2,test1后加载完打印test1,最后触发onload
结论:
- 不设置async和defer时,页面会等script下载执行完后继续执行
- 设置defer时,会下载脚本,可是不会当即执行而且按照script顺序触发
- 设置async时,会下载脚本,可是不会当即执行并不必定按照script顺序触发
- 不管是否设置了defer或async,该script会在onload前执行
- IE/chrome在设置defer时,与firefox不一样,前者会等脚本都执行后才执行DOMContentLoaded,然后者会先于脚本执行