javascript - 明明一个费时js写在body结尾,为什么页面要等到差不多js加载完才呈现?
问题描述
最近在思考有关css和js在页面中位置对页面加载以及性能的影响,也写了几个demo,发现了一些疑问,如把一些费时的js放在body底部防止阻塞页面的加载。而我敲的demo却好像不符合大家一直所说的。具体代码如下:
<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title>Title</title></head><body><p>我是第1行</p><p>我是第2行</p><p>我是第3行</p><p>我是第4行</p><p>我是第5行</p><p>我是第6行</p><script> console.time('t1'); var str =0; for(var i = 0;i<500000000;i ++){str +=i; } console.timeEnd('t1'); alert(str);</script></body></html>
按理说应该是先呈现6个P元素,然后等若干秒再alert (str).可是结果却不是这样,下面是这段代码在几个浏览器中运行的情况:1.chrome中是等加载条转啊转,然后alert,点击确定后呈现页面;2.ie 和 火狐中是等加载条转啊转,然后页面和alert几乎同时出现(应该是先呈现页面再alert,因为alert时候p元素已经出现了);
下面是我尝试的方法:
1.给body加onload方法:
<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title>Title</title></head><body onload = 'fn()'><p>我是第1行</p><p>我是第2行</p><p>我是第3行</p><p>我是第4行</p><p>我是第5行</p><p>我是第6行</p><script>function fn(){ console.time('t1'); var str =0; for(var i = 0;i<5000000000;i ++){str +=i; } console.timeEnd('t1'); alert(str);}</script></body></html>
结果没有任何变化;
2.用window.onload方法:
<script> function fn(){console.time('t1');var str =0;for(var i = 0;i<500000000;i ++){ str +=i;}console.timeEnd('t1');alert(str); } window.onload = fn;</script>
结果也是一样,没有任何变化;
3.将script写成外联方式,测试的结果还是一样(昨晚在家里试了一下,好像是先呈现页面元素再加载js,不过现在也无从考证,不知道会不会是浏览器版本问题);附:怎么感觉不同浏览器运算速度不一样啊,5亿次循环在谷歌中10秒钟,火狐只花了6秒,也不是很理解
第一次来提问,望各位大牛轻虐 0.0~ 在这里先谢谢了
问题解答
回答1:楼上说的有道理,应该是由于for循环占用了CPU资源导致首屏加载变慢。即使在body底部的script标签也会拖慢首屏出来的速度,因为浏览器在最一开始就会请求它对应的js文件,而这,占用了有限的TCP链接数、带宽甚至运行它所需要的CPU。
回答2:script标签放在body的底部,是防止script标签阻塞其他页面资源文件的下载,加快页面相关资源的加载。但整个页面渲染,仍会被script标签终止,因此在你的例子中看到页面一直是空白,直到script脚本运算完成后,页面渲染完才能显示出来。
在你给的例子中,如果想让页面先显示出来,然后再进行script脚本计算,可以使用setTimeout让脚本异步执行,如:
setTimeout(function() { //需要执行将脚本...}, 0);回答3:
我猜这是因为这占用了太多 CPU 资源导致的,页面渲染也需要 CPU 资源
如果把这个费时操作换成 IO 的,我觉得就会符合预期了
PS:猜测,待空了试试