script關於async與defer屬性的測試

環境:

  1. chrome31/firefox25/IE11(其它版本沒有測試),下列簡稱chrome/firefox/IE
  2. 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/');

測試步驟:

  1. 不爲script設定defer或async時

    • 頁面會在全部script加載和執行完後渲染 ,輸出test一、test2和test3,DOMContentLoaded,onload
  2. 設置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
  3. 設置asyncnode

    • test1爲async ,等test2的3秒延遲後,會當即輸出test2和test3並觸發DOMContentLoaded,等test1的5秒後會打印test1,最後觸發onload
    • test1和test2都爲async時 ,會當即輸出test3並觸發DOMContentLoaded,test2先加載完先打印test2,test1後加載完打印test1,最後觸發onload

結論:

  1. 不設置async和defer時,頁面會等script下載執行完後繼續執行
  2. 設置defer時,會下載腳本,可是不會當即執行而且按照script順序觸發
  3. 設置async時,會下載腳本,可是不會當即執行並不必定按照script順序觸發
  4. 不管是否設置了defer或async,該script會在onload前執行
  5. IE/chrome在設置defer時,與firefox不一樣,前者會等腳本都執行後才執行DOMContentLoaded,然後者會先於腳本執行
相關文章
相關標籤/搜索