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

时间:2010-12-09 09:52:37

标签: javascript html performance optimization

如果脚本标签位于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>代码中的所有内容!!

加载时如何影响网页的效果?真的吗? 哪一个是最好的,要么是这三个还是其他一个你知道的?

还有一件事,我在谷歌上搜索了一下,我从这里开始:Best Practices for Speeding Up Your Web Site它建议put scripts at the bottom,但传统上很多人把它放在<head>标签中,这是在<body>标记之上。我知道这不是一个规则,但许多人更喜欢这样。如果您不相信,只需查看此页面的来源!并告诉我什么是最佳表现的更佳风格。

8 个答案:

答案 0 :(得分:66)

默认情况下,Javascript资源会阻止任何其他并行下载的发生。因此,您可以想象如果头部有足够的<script>个标签,则调用多个外部脚本会阻止HTML加载,从而问候用户使用空白屏幕,因为没有其他内容在您的页面上将加载直到 JS文件已完全加载。

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

或者,您可以选择异步加载Javascript文件。有很多现有的方法可以通过以下方法实现:

XHR Eval

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();

仅举几例......

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


对于IE,您可以使用defer属性,如下所示:

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

设置时,此布尔属性   向用户代理提供一个提示   该脚本不会生成   任何文件内容(例如,没有   javascript中的“document.write”和   因此,用户代理可以继续   解析和渲染。

答案 1 :(得分:23)

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

你把jQuery标签放在哪里并不重要:

  

最后,关于持久民俗的一句话。你可能遇到过   经常重复的建议“总是把JavaScript放在   在结束标记之前的页面底部“。这曾经是一次   是的,因为Web浏览器按顺序加载脚本并阻止   加载和呈现,直到每个脚本完成。这不是   更长的真实;现代浏览器“预加载扫描”并开始加载   并行的所有脚本,无论是在head元素中还是在head元素中列出的   页面底部。外部JavaScript通常是异步加载的   并写入,因此它将不会执行,直到页面加载和   DOM准备好了。在head元素中加载脚本不再是坏事   实践。

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

答案 2 :(得分:16)

文档顶部的脚本元素可以更快地使用(因此您可以绑定事件处理程序并在元素可用时立即运行JS),但它们会阻止解析页面的其余部分。

底部的脚本元素不是(所以你不能)并且没有任何重要的页面,所以如果它被阻止也没关系。

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

请注意,底部的脚本元素必须在body元素中 。所以它应该是:

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

而不是

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

答案 3 :(得分:11)

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

JavaScript的问题在于阻止了页面其余部分的执行/加载。如果你的JavaScript中需要花费很长时间,那么它将阻止页面的其余部分加载:

请参阅以下示例:

您可以看到警报对页面其余部分的渲染效果。您放在页面顶部的任何JavaScript都会产生相同的效果。一般来说,最好放置对页面布局至关重要的东西(即菜单插件或其他东西)。任何需要用户交互(弹出处理程序)或根本不涉及用户(Google Analytics)的内容都应该转到页面底部。

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

答案 4 :(得分:5)

是的,它确实会影响网页加载的效果。

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

现在有人可能会注意到,如果在脚本标记中使用async="true",则不会阻止。但是这只得到了几个浏览器的支持,所以这对一般情况没有帮助。

无论哪种方式,通常最好将脚本标记放在页面底部,这样它们就不会占据页面的其他部分。

答案 5 :(得分:4)

首先,不在body / head元素内部的脚本标记会创建无效的HTML,甚至可能会在某些浏览器中导致一些异常。

在渲染任何HTML之前,将加载和解释head元素内的脚本标记,这会阻止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将在paralel中加载,因此HTML / CSS渲染得非常好。

答案 6 :(得分:1)

脚本本身的性能肯定是一样的。

但是,如您所链接的文章所述,展示位置非常重要,因为浏览器会在遇到并加载{{1}的内容时“暂停”(或“冻结”)同时下载和呈现页面} 标签。因此,最好让浏览器呈现页面并应用CSS样式,然后包含您的<script>。它会让用户看起来更顺畅。

此外,在底部包含脚本可能意味着在您关闭.js标记之前。

答案 7 :(得分:-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有任何此类依赖性。

参考:Detailed problem description