您的位置:首页 > Web前端 > JavaScript

js位置对浏览器加载页面的影响

2016-01-27 17:58 579 查看
js位置对浏览器加载页面的影响
现在对于JS的位置,通常有这么一个说法:
现代浏览器很聪明,会进行 prefetch 优化,在 UI update 线程之外,还会开启另一个线程,对后续 JS 和 CSS 提前下载, JS 和 CSS 的下载是同步进行的,和位置无关。那么我们来验证下,具体情况会是什么样呢?
以下测试基于chrome版本 47.0.2526.106 (64-bit)
先编写一个演示用的HTML页面,用于做加载测试
<html>
<header>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrmoe=1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>JS加载测试</title>
<meta name="description" content="JS加载测试">
</header>
<body>
<div id="id1" style="height:100px;width:200px;background-color: red">123</div>
<div id="id2" style="height:100px;width:200px;background-color: blue">321</div>
</body>
</html>


先把test的加载位置分别放在header,body中,body尾部外来分别看显示效果
三种情形的代码如下
放在header:
<html>
<header>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrmoe=1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>JS加载测试</title>
<meta name="description" content="JS加载测试">
<script src="/assets/js/testjs.js?v=$!{ver}"></script>
</header>
<body>
<div id="id1" style="height:100px;width:200px;background-color: red">123</div>
<div id="id2" style="height:100px;width:200px;background-color: blue">321</div>
</body>
</html>


放在body中:
<html>
<header>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrmoe=1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>JS加载测试</title>
<meta name="description" content="JS加载测试">
</header>
<body>
<div id="id1" style="height:100px;width:200px;background-color: red">123</div>
<script src="assets/js/testjs.js?v=$!{ver}"></script>
<div id="id2" style="height:100px;width:200px;background-color: blue">321</div>
</body>
</html>


放在body后:
<html>
<header>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrmoe=1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>JS加载测试</title>
<meta name="description" content="JS加载测试">
</header>
<body>
<div id="id1" style="height:100px;width:200px;background-color: red">123</div>
<div id="id2" style="height:100px;width:200px;background-color: blue">321</div>
</body>
<script src="/assets/js/testjs.js?v=$!{ver}"></script>
</html>


三次的加载时间分别如下
放在header



放在body中



放在body外



可以看出,时间都相差不多
结论1:正常加载情况下,js无论放在哪里都不影响页面展示。

上面是正常情况。下面我们来模拟下阻塞加载的情形,在filter中添加如下代码,当请求是testjs的时候,我们让线程睡眠20秒。
if(((HttpServletRequest) request).getRequestURI().contains("testjs")){
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}


三次加载情况如下
放在header:
页面展示效果和访问时间:





20秒后



可以看出,在JS未加载完成之前,页面是无法展示的(即使页面不依赖该JS)

放在body中:
页面展示效果和时间:





20秒后



可以看出,在body中的JS加载阻断了页面DOM树的构建,导致id2的DIV在js加载完成之前无法展示。

放在body后:
页面展示效果和时间:





20秒后



可以看出,JS放尾部不影响页面的最初展示,只影响页面整体加载完成时间。
结论2:在阻塞情况下,JS的加载会阻断其后的HTML渲染,影响用户首次看到页面的效果。

那么,问题来了,既然阻塞情况下后续的DOM没有展示,那么究竟是DOM树未构建完成呢?还是只是中断了渲染?我们修改下代码
<html>
<header>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrmoe=1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>JS加载测试</title>
<meta name="description" content="JS加载测试">
<script>
console.log(document.getElementById("id2"))
</script>
</header>
<body>
<div id="id1" style="height:100px;width:200px;background-color: red">123</div>
<script src="/assets/js/testjs.js?v=$!{ver}"></script>
<div id="id2" style="height:100px;width:200px;background-color: blue">321</div>
<script>
console.log("after testjs loaded")
console.log(document.getElementById("id2"))
</script>
</body>
</html>


然后执行,观察console里面的输出



可以看出,在testjs加载完成之前,是无法获取到id2的DOM对象的,可以推断JS加载会阻断DOM树的构建。
那么阻断的JS会影响后续其他JS加载吗?
我们将tests在body中同样的位置复制2份,改名为test1.js和test2.js,观察网络请求



可以看到,阻断的JS不会影响到其他JS的下载,下载JS几乎是同时进行的。

结论:正常情况下,JS无论放在哪里加载都不会影响到页面的最初呈现效果,但是在阻塞情况下,JS加载会中断HTML的内容,影响用户首次看到的页面效果。无论阻塞与否,都不影响页面的最终加载时间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: