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





目录
相关文章
|
5天前
|
Web App开发 前端开发 JavaScript
JavaScript动态渲染页面爬取——Selenium的使用(一)
JavaScript动态渲染页面爬取——Selenium的使用(一)
14 4
|
5天前
|
Web App开发 数据采集 JavaScript
JavaScript动态渲染页面爬取——Selenium的使用(二)
JavaScript动态渲染页面爬取——Selenium的使用(二)
12 2
|
4天前
|
JavaScript 前端开发 API
JavaScript全屏,监听页面是否全屏
JavaScript全屏,监听页面是否全屏
19 0
|
6天前
|
前端开发 JavaScript
JavaScript动态渲染页面爬取——CSS位置偏移反爬案例分析与爬取实战
JavaScript动态渲染页面爬取——CSS位置偏移反爬案例分析与爬取实战
13 0
|
6天前
|
存储 JSON JavaScript
JavaScript动态渲染页面爬取——Pyppeteer爬取实战
JavaScript动态渲染页面爬取——Pyppeteer爬取实战
12 0
|
7天前
|
机器学习/深度学习 自然语言处理 前端开发
前端大模型入门:Transformer.js 和 Xenova-引领浏览器端的机器学习变革
除了调用API接口使用Transformer技术,你是否想过在浏览器中运行大模型?Xenova团队推出的Transformer.js,基于JavaScript,让开发者能在浏览器中本地加载和执行预训练模型,无需依赖服务器。该库利用WebAssembly和WebGPU技术,大幅提升性能,尤其适合隐私保护、离线应用和低延迟交互场景。无论是NLP任务还是实时文本生成,Transformer.js都提供了强大支持,成为构建浏览器AI应用的核心工具。
61 0
|
7天前
|
缓存 前端开发 算法
浅谈【JavaScript】的浏览器指纹?
浅谈【JavaScript】的浏览器指纹?
9 0
|
21天前
|
JavaScript 前端开发
js之浏览器对象|28
js之浏览器对象|28
|
2月前
|
机器学习/深度学习 人工智能 前端开发
【人工智能】利用TensorFlow.js在浏览器中实现一个基本的情感分析系统
使用TensorFlow.js在浏览器中进行情感分析是一个非常实用的应用场景。TensorFlow.js 是一个用于在JavaScript环境中训练和部署机器学习模型的库,使得开发者能够在客户端直接运行复杂的机器学习任务。对于情感分析,我们可以使用预先训练好的模型来识别文本中的积极、消极或中性情感。
72 4
【人工智能】利用TensorFlow.js在浏览器中实现一个基本的情感分析系统
|
2月前
|
机器学习/深度学习 存储 前端开发
实战揭秘:如何借助TensorFlow.js的强大力量,轻松将高效能的机器学习模型无缝集成到Web浏览器中,从而打造智能化的前端应用并优化用户体验
【8月更文挑战第31天】将机器学习模型集成到Web应用中,可让用户在浏览器内体验智能化功能。TensorFlow.js作为在客户端浏览器中运行的库,提供了强大支持。本文通过问答形式详细介绍如何使用TensorFlow.js将机器学习模型带入Web浏览器,并通过具体示例代码展示最佳实践。首先,需在HTML文件中引入TensorFlow.js库;接着,可通过加载预训练模型如MobileNet实现图像分类;然后,编写代码处理图像识别并显示结果;此外,还介绍了如何训练自定义模型及优化模型性能的方法,包括模型量化、剪枝和压缩等。
38 1