script的加载方式与执行

script通常是阻塞式加载的,H5新增了asyncdefermodule特性,可用于异步加载/延迟执行:javascript

schematic diagram

  • async 属性是指当这个 script 可用时,就异步执行它
  • defer 属性是指当页面被解析完毕后,才能执行
  • 若是以上两个属性都没有,则马上下载并执行,同时阻止页面的解析,直到执行完毕
  • module 属性是指关联脚本所有下载后才会执行,且不受defer影响

标准定义详见:https://html.spec.whatwg.org/#the-script-elementhtml

关于async和defer

aysnc 的 script 不能保证在 jQuery(document).ready 的时候是可用的,而 defer 能够。java

这篇博文给出了以下测试结果:web

jQuery(document).ready 的执行时序。
Chrome 下是:defer -> jQuery(document).ready -> async -> window.onload。
Firefox 下是:async -> defer -> jQuery(document).ready -> window.onload。
我又把 JavaScript 的下载速度变慢,发现结果仍然没有变化。

因此使用async的时候须要谨慎,全局的属性和方法最好提早定义。浏览器

动态加载javascript基本

还有一个经常使用的技巧是,在须要的时候动态加载脚本——好比日期插件、地区选择插件,等等——以便加快页面载入速度。该博文也提到了相关方法及一些坑。app

不过这里我关心的是执行时机。onload事件被认为是能够确保在SCRIPT执行完成后立刻被执行,但实际使用中发现,此时它仍有可能未完成初始化,若是当即执行callback可能会出问题,对于体积较大的插件(如echarts),出错的几率明显变大。echarts

因此,应当把onload当作loaded事件处理。而后使用setTimeout方法延迟执行callback,以保障它真的执行完毕了。不过期间阈值很差定,这也是个坑。异步

后来发现了beforescriptexecuteafterscriptexecute,<del>但貌似只有Firefox支持</del>当前无浏览器支持,并且若是这个script标签是用appendChild()等方法动态添加上去的,则不会触发该事件,暂时是无望了。async

暂时没找到更好的办法。欢迎你们出主意:-)测试

相关文章
相关标签/搜索