HTML中的<script>标记位置是否会影响网页的性能?


69

如果脚本标签在HTML页面中的正文上方或下方,那么这对网站的性能有影响吗?

以及如果在这样之间使用:

<body>
..blah..blah..
<script language="JavaScript" src="JS_File_100_KiloBytes">
function f1() {
.. some logic reqd. for manipulating contents in a webpage
}
</script>
... some text here too ...
</body> 

还是更好?

<script language="JavaScript" src="JS_File_100_KiloBytes">
function f1() {
.. some logic reqd. for manipulating contents in a webpage
}
</script>
<body>
..blah..blah..
..call above functions on some events like onclick,onfocus,etc..
</body> 

还是这个?

  <body>
    ..blah..blah..
    ..call above functions on some events like onclick,onfocus,etc..
<script language="JavaScript" src="JS_File_100_KiloBytes">
    function f1() {
    .. some logic reqd. for manipulating contents in a webpage
    }
    </script>
    </body> 

不必告诉一切<html>标签中的所有内容!!

加载时如何影响网页的性能?真的吗 在这3个或您知道的其他3个中,哪个是最好的?

还有一件事情,我在Google上搜索了一下,然后从这里开始:加速网站的最佳实践,它建议将脚本放在底部,但是传统上,很多人将其放在<head>标签上方的<body>标签中。我知道这不是规则,但许多人都喜欢这样。如果您不相信,请查看此页面的源代码!并告诉我什么是获得最佳性能的更好风格。


我认为这已经在讨论中了,所以在这里这里也可以看到。
Pratik 2010年

Answers:


71

默认情况下,JavaScript资产倾向于阻止任何其他并行下载的发生。因此,您可以想象如果<script>头部中有很多标签,则调用多个外部脚本将阻止HTML加载,从而向用户显示空白屏幕,因为除非JS文件包含,否则页面上的其他内容都不会加载完全加载。

为了解决这个问题,许多开发人员选择将JS放在HTML页面的底部(在</body>标记之前)。这似乎是合乎逻辑的,因为在大多数情况下,直到用户开始与网站进行交互才需要JS。将JS文件放在底部也可以进行渐进式渲染。

另外,您可以选择异步加载Javascript文件。有许多现有方法可以通过以下方法实现:

XHR评估

var xhrObj = getXHRObject();
xhrObj.onreadystatechange = 
  function() { 
    if ( xhrObj.readyState != 4 ) return;
    eval(xhrObj.responseText);
  };
xhrObj.open('GET', 'A.js', true);
xhrObj.send('');

脚本DOM元素

var se = document.createElement('script');
se.src = 'http://anydomain.com/A.js';
document.getElementsByTagName('head')
[0].appendChild(se);

Meebo Iframed JS

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
var doc = iframe.contentWindow.document;
doc.open().write('<body onload="insertJS()">');
doc.close();

仅举几例...

注意:在当前浏览器中,最多只能并行加载五个脚本。


因为IEdefer可以像这样使用的属性:

<script defer src="jsasset.js" type="text/javascript"></script>

设置后,此布尔属性会向用户代理提示该脚本将不会生成任何文档内容(例如,在javascript中不会生成“ document.write”),因此,用户代理可以继续解析和渲染。


如果两个js文件来自不同的路径或服务器,即使它们可以同时加载怎么办?
Pratik 2010年

@Rahul Joshi当然。高流量站点通常倾向于投资内容交付网络,该网络是用于静态内容的无cookie域。因此,是的,两个js文件可以来自不同的服务器,尽管加载时间将取决于所讨论的服务器。
罗素·迪亚斯

但这可以同时进行,从而减少了总体时间?
Pratik 2010年

@Rahul Joshi抱歉,是的,可以。并没有真正减少总时间,只是将内容的大部分更快地呈现给用户。实际上,它被认为加载得更快。
罗素·迪亚斯

看起来很有趣,但是您的图片却显示404。您有替换图片网址吗?
雅各布

28

所以我知道这是一个古老的讨论,但是我一直在阅读有关此主题的内容,并在StackOverflow上阅读其他答案...

实际上,再也没有在哪里放置jQuery标签都无关紧要了:

最后,关于持续的民间传说。您可能会遇到经常重复提出的建议,即“始终将JavaScript放在页面底部,紧接在结束标记之前”。这曾经是真的,因为Web浏览器会顺序加载脚本,并阻止加载和渲染,直到每个脚本完成为止。这不再是事实;现代浏览器会执行“预加载扫描”,并开始并行加载所有脚本,无论是在head元素中还是在页面底部列出。外部JavaScript通常是异步加载和编写的,因此只有在页面加载和DOM准备就绪后才能执行。在head元素中加载脚本不再是一种坏习惯。

http://railsapps.github.io/rails-javascript-include-external.html


1
在不必担心<script>标签放置之前,您还需要选择其他许多较低性能的成果,因此代码具有可维护性,易于开发性和可读性。
Daniel Sokolowski

1
因为这是一个古老的讨论,所以您的答案现在变得更有意义。而且它现在也很旧;)
Matthieu

18

文档顶部的脚本元素将尽快可用(因此您可以绑定事件处理程序,并在元素可用时尽快运行JS),但是它们确实阻止了页面其余部分的解析。

底部的脚本元素不是(所以您不能),也没有任何重要的页面,因此被阻止并不重要。

哪个最好取决于相对重要性使JS运行Vs的优先级(必须根据具体情况确定)。具有HTML呈现。

请注意,底部的脚本元素必须出现body元素内。因此应该是:

<script>...</script></body></html>

并不是

</body><script>...</script></html>

12

是的,它确实会影响网页的性能。

JavaScript的问题是阻止了页面其余部分的执行/加载。如果您的JavaScript中的内容需要很长时间,那么它将阻止页面其余部分的加载:

请参阅以下示例:

您可以看到警报对页面其余部分的呈现的影响。放在页面顶部的所有JavaScript都将具有相同的效果。通常,最好将对页面布局至关重要的任何内容(例如菜单插件或其他内容)放进去。任何需要用户交互(弹出式处理程序)或完全不涉及用户(Google Analytics(分析))的内容都应转到页面底部。

您可以使用惰性加载程序,将script标签插入代码中。由于代码不在HTML上,因此可以确保整个页面均已正确呈现,并且所包含的JS不会阻止任何内容。


在Safari 8中,每个示例都是完全相同的,并且警报会阻止所有内容。
Daniel Wood

此代码示例演示上面答案描述的现代浏览器的工作方式。
kidkkr

5

是的,它确实会影响网页加载的性能。

问题是,普通<script>标签被阻塞,因此脚本标签之后的所有内容都必须等待脚本标签完成加载和解析,然后才能加载页面的其余部分。

现在可能有人会注意到,如果您async="true"在script标签中使用它,它将不会被阻止。但这仅受几个浏览器支持,因此尚不能解决一般情况。

无论哪种方式,总的来说,将脚本标签放在页面底部是一个好主意,这样它们就不会占用页面的其他部分。


脚本的位置不会影响页面加载的速度-这取决于您的Internet连接。它实际上会影响感知的性能-页面的可见元素首先加载(而不是必须等待脚本加载),因此页面加载的速度似乎比平时要快,而实际上花费的时间却相同。
whostolemyhat 2010年

@What:不幸的是,由于您的浏览器在加载脚本标签时阻止浏览器加载其他文件,因此并不完全正确,从而导致页面加载速度变慢。在加载页面时,页面将无法加载图像,而在整个页面加载过程中,图像通常可以并行加载。
Wolph 2010年

4

首先,不在正文/头部元素内部的脚本标签会创建无效的HTML,甚至可能在某些浏览器中引起某些异常。

head元素内部的脚本标签将在呈现任何HTML之前加载和解释,这会阻止HTML / CSS呈现。

body标签底部的脚本标签不会阻止HTML / CSS,并且由于您只能在DomReady上使用DOM,因此这是放置JavaScript的最佳位置。另外,您甚至不需要使用domReady事件包装器。

另外,您也可以使用LABJSRequireJS之类的库从head标签开始JavaScript(最小的HTML / CSS阻止)。通过这两个库之一加载的任何脚本都将与HTML / CSS渲染并行运行。

<head>
   <script data-main="INITSCRIPT.js" src="require.js"></script>
</head>

INITSCRIPT.js

require( [ "jQuery" , "somePlugin" ] , function(){
   $(document).ready(function(){
      $("#someId").somePlugin();   
   });
} );

在上面的示例中,只有require.js的加载和解释会阻止HTML / CSS渲染,这通常是无关紧要的。之后,jQuery和somePlugin将以并行方式加载,因此HTML / CSS呈现得很好。


1

脚本本身的性能肯定会相同。

不过,正如您所链接的文章中所述,该位置很重要,因为当浏览器遇到并加载<script>标签内容时,浏览器将“暂停”(或“冻结”)页面的同时下载和呈现。因此,最好让浏览器呈现页面并应用CSS样式,然后包含您的.js。对用户而言,它将看起来更平滑。

另外,在底部包含脚本可能意味着在关闭<body>标签之前。


-1

除性能方面外,每当将<script>标记包含在标记内时,您还需要小心<head>

让我们考虑以下示例:

<head>
 <script>document.getElementById("demo").innerHTML="hello";</script>
</head>
<body>
 <p id="demo">The content of the document......</p>
</body>

在这里,请注意,在加载DOM(或<p>标记)之前先加载脚本,这会导致脚本失败(因为getElementById无法找到名称为'demo'的元素)。

在这种情况下,您仅需在body标签内使用脚本。

考虑其他答案,最好让脚本始终位于</body>标记之前, 因为您永远不知道要从外部加载的脚本是否对DOM具有任何此类依赖性。

参考:详细的问题描述

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.