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