默认情况下,浏览器是同步加载 JavaScript 脚本,即渲染引擎遇到<script>标签就会停下来,等到执行完脚本,再继续向下渲染。如果是外部脚本,还必须加入脚本下载的时间。
script标签中属性defer是“渲染完再执行”,async是“下载完就执行”。
如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。
type="module"
script标签type属性取值为“module”,都是异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本。type="module"等同于defer属性,使用相同的执行队列,谁在前面谁先执行。
<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';
必须要/、./、../打头
普通情况
如下执行顺序,内联defer、1.js、module.js、defer.js、内联模块。
<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,一旦加载完毕,立即执行。
不携带凭证信息
<!-- 请求脚本时会携带相关凭证 (如 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 的响应头。
各大浏览器的情况:
- 请求同源模块时,Chrome 会携带凭证信息
- 即使添加了 crossorigin 属性,Safari 在请求同源脚本时也不会携带凭证信息
- Edge 则完全弄反了。请求同源模块时,Edge 默认会发送凭证信息,但如果手动添加了 crossorigin 属性,则又不会携带
- Firefox 是唯一正确实现这一点的浏览器 —— 好样的!
参考地址如下: