浏览器加载 JavaScript 脚本,主要通过元素完成。加载外部脚本时 浏览器会暂停页面渲染,等待脚本下载并执行完成后,再继续渲染。因此当js脚本数量比较多,并且都是同步加载时,就很容易造成页面加载时间过长,性能差的表现; v2-757212b6ecac206528be7c3e7e0ed135_1200x500.jpg
- 异步加载又叫非阻塞加载,浏览器在下载执行js的同时,还会继续进行后续页面的处理。
[h1]异步加载js的几种方式[/h1]- async 方式
- defer 方式
- 动态创建 script 标签
[h1]1、defer 属性[/h1]- defer属性在IE4.0就出现了。
- defer属声明脚本中将不会有document.write和dom修改。
- 浏览器会并行下载其他有defer属性的script,在HTML解析完之后才会执行下载好的脚本,不会阻塞页面后续处理。
- defer脚会按照加载顺序执行的。
如果脚本不会改变文档的内容,可将 defer 属性加入到 script 标签中,以便加快处理文档的速度。
通过给属性,将脚本文件设置为延迟加载,当浏览器遇到带有属性的- [/code]标签时,会再开启一个线程去下载[code]js
复制代码 文件,同时继续解析文档,等全部解析完毕加载完成之后,再去执行加载好的文件。这种方式只适用于引用,如果是多个脚本,该方法可以确保所有设置了 defer 属性的脚本按引入顺序执行,但是要注意,添加defer属性的js文件不应该使用document.write方法。[h1]2、async 方式[/h1]- async 属性是 HTML5 新增属性,需要 Chrome、FireFox、IE9+ 浏览器支持,
- async 属性加载完之后立即执行,如果是多个,执行顺序和加载顺序无关
- async 属性仅适用于外部脚本
- 如果是多个脚本,该方法不能保证脚本按顺序执行
属性和属性类似,也是会开启一个线程去下载js文件,但和不同的时,它会在,而不是会等到DOM加载完成之后再执行,所以还是有。
同样的,,也不能在js中使用document.write方法,但是- 对多个带有async的js文件,它不能像defer那样保证按顺序执行
复制代码 ,它是哪个js文件先下载完就先执行哪个。- [/code][h1]3、 动态创建 script 标签[/h1][code](function(){ var scriptEle = document.createElement("script"); scriptEle.type = "text/javasctipt"; scriptEle.async = true; scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js"; var x = document.getElementsByTagName("head")[0]; x.insertBefore(scriptEle, x.firstChild); })();
复制代码- (function(){ if(window.attachEvent){ window.attachEvent("load", asyncLoad); }else{ window.addEventListener("load", asyncLoad); } var asyncLoad = function(){ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); }})();
复制代码 上面两种方法中,第一种方式执行完之前会阻止onload事件的触发,而现在很多页面的代码都在onload时还执行额外的渲染工作,所以还是会阻塞部分页面的初始化处理。第二种则不会阻止onload事件的触发。
这里要简要说明一下window.DOMContentLoaded和window.onload这两个事件的区别,前者是在DOM解析完毕之后触发,这时候DOM解析完毕,JavaScript可以获取到DOM引用,但是页面中的一些资源比如图片、视频等还没有加载完,作用同jQuery中的ready事件。后者则是页面完全加载完毕,包括各种资源。
[h2]什么时候用defer,什么时候用async呢?[/h2]一般来说,两者之间的选择则是,有依赖的话应当要保证执行顺序,应当使用defer没有依赖的话使用async,同时使用的话defer失效。要注意的是两者,这个导致整个页面被清除。 参考:
- https://mp.weixin.qq.com/s/MDk7aSAECMF_e4I39EwA9w
- https://juejin.im/post/5bcdaed7e51d457a8254e1b7
- https://blog.csdn.net/weixin_39805338/article/details/80770098
|
|