script標籤中屬性defer是「渲染完再執行」,async是「下載完就執行」。html
若是有多個defer腳本,會按照它們在頁面出現的順序加載,而多個async腳本是不能保證加載順序的。瀏覽器
script標籤type屬性取值爲「module」,都是異步加載,不會形成堵塞瀏覽器,即等到整個頁面渲染完,再執行模塊腳本。type="module"等同於defer屬性,使用相同的執行隊列,誰在前面誰先執行。bash
<script src="./test.js" async></script>
<script src="./test.js" defer></script>
//寫法1
<script src="./test.js" type="module"></script>
//寫法2
<script type="module">
//code
</script>
複製代碼
// 支持
import {foo} from 'https://jakearchibald.com/utils/bar.js';
import {foo} from '/utils/bar.js';
import {foo} from './bar.js';
import {foo} from '../bar.js';
// 不支持
import {foo} from 'bar.js';
import {foo} from 'utils/bar.js';
複製代碼
必需要/、./、../打頭cookie
以下執行順序,內聯defer、1.js、module.js、defer.js、內聯模塊。ecmascript
<script src="./module.js" type="module"></script>
<script src="./defer.js" defer></script>
<script type="module">
console.log('init module');
</script>
<script defer>
//會忽略defer,當正常腳本
console.log('defer');
</script>
<script src="./1.js"></script>
複製代碼
async + module,腳本及其引入的模塊加載完成後當即執行。異步
//firefox不支持此模式
<script async type="module">
import {addTextToBody} from './utils.js';
addTextToBody('Inline module executed.');
</script>
<script async type="module" src="1.js"></script>
複製代碼
與正常腳本相同,帶有 async 屬性的腳本在下載時不會阻塞 HTML parser,一旦加載完畢,當即執行。async
<!-- 請求腳本時會攜帶相關憑證 (如 cookie) -->
<script src="1.js"></script>
<!-- 不會攜帶相關憑證 -->
<script type="module" src="1.js"></script>
<!-- 會攜帶相關憑證 -->
<script type="module" crossorigin src="1.js?"></script>
<!-- 不會攜帶相關憑證 -->
<script type="module" crossorigin src="https://other-origin/1.js"></script>
<!-- 會攜帶相關憑證-->
<script type="module" crossorigin="use-credentials" src="https://other-origin/1.js?"></script
複製代碼
對於一個同源的模塊腳本,能夠爲其添加 crossorigin 屬性,這樣在請求時就能夠攜帶相關憑證了。若是你還想將憑證發給其餘域,請使用 crossorigin="use-credentials"。須要注意的是,接收憑證的域必須返回 Access-Control-Allow-Credentials: true 的響應頭。ui
各大瀏覽器的狀況:spa
參考地址以下:firefox