js 加载方式

228 阅读2分钟

浏览器加载

同步加载

<!--页面内嵌-->
<script type="application/javascript">
// module code
</script>
<!--外部脚本-->
<script src="myModule.js" type="application/javascript></script>

默认情况下,浏览器是同步按顺序加载js脚本,当渲染引擎遇到<script>标签会停下来,等到执行完脚本在继续往下渲染,如果是外部脚本,还需要加上脚本的下载时间。这就是为什么提倡把js加在页面底部的原因,防止页面渲染阻塞。

异步加在

关键字:defer async 渲染引擎遇到这行命令后,会开始下载,但不会等它下载和执行,而是继续后面的执行命令

<script src = "myModule" defer></script>
<script src = "myModule" async></script>

defer与async区别 defer 渲染完再执行,当有多个defer时,会按顺序加载 async 下载完就执行,当有多个async时,不一定按顺序加载

加载ES6模块

<script src="myModule.js" type="module"></script>
<!--等同于-->
<script src="myModule.js" type="module" defer></script>

内嵌ES6模块

<script type="module">
    import a from "a.js";
    <!--do other-->
</script>

对于外部的模块,注意点: 1、模块脚本自定采用严格模式 2、模块中可使用import命令加载其他模块 3、模块中顶层的this返回undefined 4、同一模块加载多次,只执行一次 5、代码是在模块作用域之中运行,而不是在全局作用域运行。模块内部的顶层变量,外部不可见。

例如:

<!--a.js-->
import b from "b.js";
const x = 1;
console.log(x===window.x); //false
console.log(this === undefined); //true

delect x; //error ,严格模式禁止删除变量

利用顶层的this等于undefined这个语法点,可以侦测当前代码是否在 ES6 模块之中。