页⾯渲染时js阻塞的解决⽅法
⼀般地,⼀个包含外部样式表⽂件和外部脚本⽂件的HTML载⼊和渲染过程是这样的:
1. 浏览器下载HTML⽂件并开始解析DOM。
2. 遇到样式表⽂件link[rel=stylesheet]时,将其加⼊资源⽂件下载队列,继续解析DOM。
3. 遇到脚本⽂件时,暂停DOM解析并⽴即下载脚本⽂件。
4. 下载结束后⽴即执⾏脚本,在脚本中可访问当前<script>以上的DOM。
5. 脚本执⾏结束,继续解析DOM。
6. 整个DOM解析完成,触发DOMContentLoaded事件。
什么是阻塞?
  在页⾯中我们通常会引⽤外部⽂件,⽽浏览器在解析HTML页⾯是从上到下依次解析、渲染,如果<head>中引⽤了⼀个a.js⽂件,⽽这个⽂件很⼤或者有问题,需要2秒加载,那么浏览器会停⽌渲染页⾯(此时是⽩屏显⽰,就是页⾯啥都没有),2秒后加载完成才会继续渲染,这个就是阻塞。
为什么会阻塞?
  因为浏览器不知道a.js中执⾏了哪些脚本,会对页⾯造成什么影响,所以浏览器会等js⽂件下载并执⾏完成后才继续渲染,如果这个时间过长,会⽩屏。
解决⽅法
1、推迟加载(延迟加载)
  如果页⾯初始的渲染并不依赖于js或者CSS可以⽤推迟加载,就是最后在加载js和css,把引⽤外部⽂件的代码写在最后。⽐如⼀些按钮的点击事件,⽐如轮播图动画的脚本也可以放在最后。
2、defer延迟加载
<script src="" defer></script>
  在⽂档解析完成开始执⾏,并且在DOMContentLoaded事件之前执⾏完成,会按照他们在⽂档出现的顺序去下载解析。效果和把script 放在⽂档最后</body>之前是⼀样的。
注:defer最好⽤在引⽤外部⽂件中使⽤,⽤了defer不要使⽤document.write()⽅法;使⽤defer时最好不
要请求样式信息,因为样式表可能尚未加载,浏览器会禁⽌该脚本等待样式表加载完成,相当于样式表阻塞脚本执⾏。
3、异步加载
async异步加载:就是告诉浏览器不必等到加载完外部⽂件,可以边渲染边下载,什么时候下载完成什么时候执⾏。
<script type="text/javascript" src="a.js" async></script>
注:⽤了async不要使⽤document.write()⽅法;使⽤async时最好不要请求样式信息,原因和defer⼀样。
script dom element法:这个⽅法是⽤js动态创建⼀个script元素添加在document中。
<script type="text/javascript">
(function() {
var s = ateElement('script');
s.async = true;                                        //这句可以删除,但是效果不变。
s.src = 'js/a.js';
var x = ElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
})();
</script>
注意:这种⽅法会阻⽌onload事件
onload时异步加载:这个和script dom element法差不多但是他不是同时执⾏js和html,他是等html的⽂件,图⽚之类的、页⾯所有的资源全部加载完成后再下载执⾏js,这样的⽅法可以避免阻塞onload事件的触发。
(function() {
function async_load(){
var s = ateElement('script');
s.async = true;
s.src = 'js/yibujiaz.js';
var x = ElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
}
if (window.attachEvent)
window.attachEvent('onload', async_load);
else
window.addEventListener('load', async_load, false);
})();
注册页面js特效
注:DOMContentLoaded与onload事件不同,DOMContentLoaded是页⾯解析完成,页⾯的dom元素可以使⽤,但是页⾯的图⽚、视频等资源可能还没加载完成

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。