1.脚本加载时机

发布于 2022年 04月 08日 15:25

脚本加载时机

javascript 标签defer和async的属性

无属性

当标签没有属性时,html文档遇到script标签会暂停解析,先解析script并执行之后继续解析html的其他标签,为了不影响html的加载,通常放在文档末尾和</body>标签之前的位置,如果脚本需要操作文档,这种做法不会获取不到标签节点的情况;

<html>
  <head></head>
  <body>
  <header></header>
  <main></main>
  <footer></footer>
  <script></script>
  </body>
</html>

defer

当标签中加入defer属性时,html文档遇到script标签不会暂停解析,而是htmlscript同时进行,解析完script之后不会立即执行,而是等待其他html的其他标签解析完成后再执行,比较大的脚本文件可以放在文档头部,可以减少等待时间,简单来说就是:立即下载,延迟执行

<html>
  <head>
  <script async src=""></script>
  </head>
  <body>
  <header></header>
  <main></main>
  <footer></footer>
  </body>
</html>

async

async 属性和 defer 都可以让脚本异步加载,不同的是async属性加载完成后会立即执行,所以适合那些不涉及文档操作的脚本,简单来说就是:立即下载,立即执行

type="module"

type="module"时,默认加上了defer标签

动态加载脚本

因为javascript可以使用DOM API,所以通过向DOM中动态添加script元素同样可以加载指定的脚本,如下:

let script = document.createElement("script");
script.src = "some.js";
document.head.appendChild(script);

相当于添加了 async属性,但并不是所有的浏览器都支持async属性,所以可以通过设置 async属性为false为统一加载行为

let script = document.createElement("script");
script.src = "some.js";
script.async = false;
document.head.appendChild(script);

此种方式加载的脚本对浏览器预加载器是不可见的,会影响在队列中的优先级,要想预加载器知道动态请求文件的存在,可以在文档头部显示声明他们:

<link rel="preload" href="some.js" >

其他

  • 包含在script标签中的代码会被从上到下解释,在使用行内script代码时,不能出现</script>,会导致浏览器报错,解决此问题可添加转义字符"\"
  • 使用了scr属性的script标签不再解释标签内的代码

推荐文章