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

简介: js位置对浏览器加载页面的影响现在对于JS的位置,通常有这么一个说法:现代浏览器很聪明,会进行 prefetch 优化,在 UI update 线程之外,还会开启另一个线程,对后续 JS 和 CSS 提前下载, JS 和 CSS 的下载是同步进行的,和位置无关。

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的内容,影响用户首次看到的页面效果。无论阻塞与否,都不影响页面的最终加载时间。





目录
相关文章
|
20天前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
18天前
|
缓存 监控 前端开发
在资源加载优化中,如何利用浏览器缓存提升性能?
通过以上这些方法,可以有效地利用浏览器缓存来提升资源加载的性能,减少网络请求次数,提高用户体验和应用的响应速度。同时,需要根据具体的应用场景和资源特点进行灵活调整和优化,以达到最佳的效果。此外,随着技术的不断发展和变化,还需要持续关注和学习新的缓存优化方法和策略。
85 53
|
21天前
|
移动开发 JavaScript 前端开发
一些处理浏览器兼容性问题的JavaScript库
这些库在处理浏览器兼容性问题方面都有着各自的特点和优势,可以根据具体的需求和项目情况选择合适的库来使用,从而提高代码的兼容性和稳定性,为用户提供更好的体验。同时,随着浏览器技术的不断发展,还需要持续关注和学习新的兼容性解决方案。
|
1月前
|
JSON 移动开发 JavaScript
在浏览器执行js脚本的两种方式
【10月更文挑战第20天】本文介绍了在浏览器中执行HTTP请求的两种方式:`fetch`和`XMLHttpRequest`。`fetch`支持GET和POST请求,返回Promise对象,可以方便地处理异步操作。`XMLHttpRequest`则通过回调函数处理请求结果,适用于需要兼容旧浏览器的场景。文中还提供了具体的代码示例。
在浏览器执行js脚本的两种方式
|
22天前
|
JavaScript 前端开发 数据处理
模板字符串和普通字符串在浏览器和 Node.js 中的性能表现是否一致?
综上所述,模板字符串和普通字符串在浏览器和 Node.js 中的性能表现既有相似之处,也有不同之处。在实际应用中,需要根据具体的场景和性能需求来选择使用哪种字符串处理方式,以达到最佳的性能和开发效率。
|
21天前
|
算法 开发者
Moment.js库是如何处理不同浏览器的时间戳格式差异的?
总的来说,Moment.js 通过一系列的技术手段和策略,有效地处理了不同浏览器的时间戳格式差异,为开发者提供了一个稳定、可靠且易于使用的时间处理工具。
28 1
|
23天前
|
缓存 前端开发 JavaScript
JavaScript加载优化
JavaScript加载优化
|
23天前
|
缓存 前端开发 JavaScript
优化CSS和JavaScript加载
优化CSS和JavaScript加载
|
25天前
|
缓存 前端开发 JavaScript
优化CSS和JavaScript加载
Next.js和Nuxt.js在优化CSS和JavaScript加载方面提供了多种策略和工具。Next.js通过代码拆分、图片优化和特定的CSS/JavaScript优化措施提升性能;Nuxt.js则通过代码分割、懒加载、预渲染静态页面、Webpack配置和服务端缓存来实现优化。两者均能有效提高应用性能。
|
1月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。