网站性能优化(三)异步加载脚本

原则上来说,HTML在使用 js1.js var xhrObj = new XMLHttpRequest(); xhrObj .onreadystatechange = function(){ if (xhrObj .readyState == 4) { var scrElem = document.createElement('script'); srcElem.text= xhrObj.responseText; document.getElementsByTagName('head')[0].appendChild(scrElem); } }; xhrObj .open('GET', 'js2.js', true); xhrObj .send('');

查看chrome developer timeline:

网站性能优化(三)异步加载脚本_第5张图片
timeline-xhr.png

优点::

  • 将脚本下载和脚本执行分离开,可以在适当的时候再执行脚本。
  • 不会阻塞onload事件

缺点::

  • 通过XMLHttpRequest获取的脚本文件必须和主页面是同一个域名下。也就是说,不支持跨域下载脚本。因此不适合加载第三方文件。
  • 脚本无序执行。

3. Script defer和async

两者都支持异步加载文件,不同之处是,defer会在全部资源下载完毕后才执行JS文件;async在脚本文件下载完就立刻执行,并且,async模式加载的JS文件无法依序执行,对于有顺序依赖的脚本来说,不应该采用这种方式。defer相对友好一些,并可以保证JS文件按照顺序执行。

稍微对程序做些修改:


网站性能优化(三)异步加载脚本_第6张图片
code2.png
网站性能优化(三)异步加载脚本_第7张图片
loading3.png

优点::

  • defer和async优点:支持跨域加载脚本文件。
  • defer优点:可以保证JS文件按照顺序执行。

缺点::

  • defer和async缺点:IE10以上(包括IE10)才支持。
  • async缺点:JS文件无法依序执行。
  • 会阻塞onload事件

4. Script in Iframe

创建了一个隐藏的iframe标签,设置其src值为JS代码,然后插入到主页面中。

这种方式在实际项目中很少用到,因为iframe是开销最高的DOM元素。常用场景是显示广告(广告一般需要运行在隔离环境中,iframe很合适)。


注意,src的值是a.html,而不是a.js,因为iframe默认其返回值为HTML文档。所以需要在HTML文档中把外部脚本转成行内脚本。

和XMLHttpRequest一样,iframe不支持跨域加载脚本,且脚本无序执行。

5. 小结

异步加载脚本还普遍存在另一个问题:无法保持多个脚本的执行顺序(除了defer)。
为了脚本依序执行,可以采用如下方法:
1)定时器
利用setTimeoutsetInterval监控第一个脚本执行情况,一旦发现被执行完,再继续执行下一个脚本。

  1. Script Onload
    利用script元素的onloadonreadystatechange事件处理程序,例子如下:

注意:script.onload/onreadystatechange事件同样会阻塞window.onload


微信公众号:

网站性能优化(三)异步加载脚本_第8张图片

你可能感兴趣的:(网站性能优化(三)异步加载脚本)