Script标签加载详解

Script标签加载详解

Posted by limantang on October 31, 2019

Script标签加载详解

script标签的几个特点

  • script标签(不含defer, async)会阻止文档的渲染, 脚本会立即下载并执行
  • script在默认情况下下载执行顺序和出现顺序一致
  • 当script标签在head标签里面时, 在下载脚本时,浏览器处于阻塞状态, 网络不好或者文件过大时,页面处于空白停顿状态
  • 当把script标签放在页面底部, 这是大家公认的提升体验的办法了, 但是这种还是存在一个问题, 在页面底部毕竟还是要等到文档流下载完毕才去下载执行, 还是会存在一个交互延迟的时间, 虽然显示时间变短了, 但是交互时间延后了—>解决方案就是async属性
  • document.ready事件要等待所有script下载完成后才能被触发

有defer和async属性

  • 有defer属性, 异步下载脚本, 但是延迟执行脚本, 相当于把script标签放入body的最底部, 也就是要等到整个页面渲染完成结束(DOM结构完全生成, 以及其他的脚本执行完成)才会执行脚本

  • async定义的脚本是否异步下载后立即执行, 取值true或者false, 如果为true, 脚本就会在页面渲染的过程中下载执行(浏览器会判断该脚本是否处于可执行状态), 而不会阻塞页面的渲染(不阻塞是指异步下载的过程中,脚本执行时还是会阻塞)

  • async不会保证脚本执行的顺序, 谁先下载完毕谁先执行

  • 如果两个属性同时存在和只存在async效果相同

  • 一句话 defer是渲染完再执行 async是下载完就执行(异步下载同步执行)

  • 浏览器兼容性查看MDN吧…

type=“module”

如果浏览器加载ES6模块(module)也是用script标签就要加入<script type=“module” src=“./foo.js”></script> 对于带有type=“module”的script都是异步加载的, 不会阻塞浏览器, 等到整个页面渲染完, 再执行模块代码, 相当于开启了defer

如果开启了async属性, 只要加载完成, 渲染引擎终端渲染, 立即执行

JS动态添加script脚本标签

JS动态添加的script脚本标签会异步的加载, 无论这个标签被添加到哪里

document.write

document.write()添加的script标签(不含defer,async)同步阻塞的下载执行 一次document.open对应一次document.write

  • 一次document.open对应一次文档流, open相当于打开一次文档流
  • document.open 会清除上一次文档流的所有节点内容, 以及所有的事件监听
  • 在一次文档流当中可以随意的document.write
  • 如果在一次文档流结束之后再次的write就会导致内容被重写覆盖, 因为在上一次文档流结束之后, 再次write会重新open打开一次文档流, 所以就覆盖了之前的内容