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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4396849/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 12:14:33  来源:igfitidea点击:

Does the <script> tag position in HTML affects performance of the webpage?

javascripthtmlperformanceoptimization

提问by Pratik

If the script tag is above or below the body in a HTML page, does it matter for the performance of a website?

如果脚本标签位于 HTML 页面正文的上方或下方,它对网站的性能有影响吗?

And what if used in between like this:

如果像这样在两者之间使用会怎么样:

<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> 

Or is this better?:

或者这更好?:

<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> 

Or this one?:

还是这个?:

  <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> 

Need not tell everything is again in the <html>tag!!

不用告诉<html>标签中的所有东西都再次出现了!!

How does it affect performance of webpage while loading? Does it really? Which one is the best, either out of these 3 or some other which you know?

加载时它如何影响网页的性能?真的吗?哪一个是最好的,无论是这三个还是你知道的其他一些?

And one more thing, I googled a bit on this, from which I went here: Best Practices for Speeding Up Your Web Siteand it suggests put scripts at the bottom, but traditionally many people put it in <head>tag which is above the <body>tag. I know it's NOT a rule but many prefer it that way. If you don't believe it, just view sourceof this page! And tell me what's the better style for best performance.

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

回答by Russell Dias

Javascript assets, by default, tend to block any other parallel downloads from occurring. So, you can imagine if you have plenty of <script>tags in the head, calling on multiple external scripts will block the HTMLfrom loading, thus greeting the user with a blank white screen, because no other content on your page will load untilthe JS files have completely loaded.

默认情况下,Javascript 资产往往会阻止任何其他并行下载的发生。所以,你可以想象如果你<script>的头部有很多标签,调用多个外部脚本会阻止HTML加载,从而用一个空白的白屏来迎接用户,因为在 JS 文件有之前不会加载页面上的其他内容完全加载。

In order to combat this issue, many developers have opted to placing JS at the bottom of the HTML page (before the </body>tag). This seems logical because, most of the time JS is not required until the user begins interacting with the site. Placing JS files at the bottom also enables progressive rendering.

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

Alternatively, you can choose to load Javascript files asynchronously. There are plenty of existing methods which this can be accomplished by:

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

XHR Eval

XHR 评估

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

Script DOM Element

脚本 DOM 元素

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

Meebo Iframed JS

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

To name a few...

仅举几例...

Note: Only a maximum of five scripts can be loaded in parallel in current browsers.

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



ForIEthere is the deferattribute you can use like so:

对于IE还有就是defer你可以使用像这样的属性:

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

When set, this boolean attribute provides a hint to the user agent that the script is not going to generate any document content (e.g., no "document.write" in javascript) and thus, the user agent can continue parsing and rendering.

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

回答by reectrix

So I know this is an old discussion, but I've been reading about this topic and reading other answers on StackOverflow...

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

It actually doesn't matter where you put the jQuery tag anymore:

实际上,将 jQuery 标记放在哪里不再重要:

Finally, a word about persistent folklore. You may have encountered the frequently repeated advice to “always place JavaScript at the bottom of the page just before the closing tag”. This was once true because web browsers loaded scripts sequentially and blocked loading and rendering until each script was complete. This is no longer true; modern browsers do “preload scanning” and begin loading all scripts in parallel, whether listed in the head element or at the bottom of the page. External JavaScript often is loaded asynchronously and is written so it won't execute until the page is loaded and the DOM is ready. Loading a script in the head element is no longer a bad practice.

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

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

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

回答by Quentin

Script elements at the top of the document are available sooner (so you can bind event handlers and have JS run as soon as an element becomes available), but they do block parsing of the rest of the page.

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

Script elements at the bottom aren't (so you can't) and there isn't any significant page left, so it doesn't matter if that is blocked.

底部的脚本元素不是(所以你不能)并且没有任何重要的页面留下,所以它是否被阻止并不重要。

Which is bestdepends on the relative importancepriority (which has to be determined on a case-by-case basis) of having the JS running Vs. having the HTML rendering.

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

Note that a script element at the bottom must appear insidethe body element. So it should be:

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

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

and not

并不是

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

回答by Jonathon Bolster

Yes, it does affect the performance of the web page.

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

The problem with JavaScript is that is blocks the execution/loading of the rest of the page. If you have something that takes a long time in your JavaScript then it will prevent the rest of the page from loading:

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

See these examples:

请参阅以下示例:

You can see the effect the alert has on the rendering of the rest of the page. Any JavaScript that you put into the top of your page will have the same effect. In general, it is better to put anything critical to the layout of your page (i.e. menu plugins or something). Anything that requires a user interaction (popup handlers) or doesn't involve the user at all (Google Analytics) should go to the bottom of the page.

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

You can get lazy loaders that will inject your scripttags into your code. Since the code isn't on the HTML, you can be sure that your whole page has rendered correctly and that the JS you're including will not block anything.

您可以获得延迟加载器,将您的script标签注入到您的代码中。由于代码不在 HTML 中,因此您可以确保整个页面已正确呈现,并且您包含的 JS 不会阻止任何内容。

回答by Wolph

Yes, it does affect the performance of the webpage loading.

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

The problem is, normal <script>tags are blocking so everything after the script tag has to wait till the script tag is done loading and parsing before the rest of the page can load.

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

Now someone will probably note that if you use async="true"in your script tag, it won't block. But that's only supported by a couple of browsers yet so that won't help the general case yet.

现在有人可能会注意到,如果你async="true"在你的脚本标签中使用,它不会阻塞。但这仅被几个浏览器支持,因此这对一般情况没有帮助。

Either way, in general it's a good idea to place your script tags at the bottom of the page so they won't hold up other parts of the page.

无论哪种方式,通常将您的脚本标签放在页面底部是个好主意,这样它们就不会阻碍页面的其他部分。

回答by BGerrissen

Firstly script tags not inside body/head elements create invalid HTML and might even cause some exceptions in some browsers.

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

Script tags inside the head element will be loaded and interpreted before any HTML is rendered, this blocks HTML/CSS rendering.

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

Script tags at the bottom of the body tag, will not block HTML/CSS and since you can only play around with the DOM on DomReady, this is the best position to put your JavaScript. As a side note, you won't even need to use a domReady event wrapper.

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

Alternatively, you can also use libraries like LABJSand RequireJSto kickstart your JavaScript from the head tag (minimal HTML/CSS blocking). Any scripts loaded through either of these libraries will run in paralel to HTML/CSS rendering.

或者,您也可以使用LABJSRequireJS 之类的库从 head 标记(最小的 HTML/CSS 阻塞)启动您的 JavaScript。通过这些库中的任何一个加载的任何脚本都将与 HTML/CSS 渲染并行运行。

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

INITSCRIPT.js

初始化脚本

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

In the above example, only the load and interpretation of require.js will block HTML/CSS rendering, which usually is insignificant. After which jQuery and somePlugin will be loaded in paralel, so HTML/CSS renders just nicely.

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

回答by Gipsy King

Performance of the script itself will definitely be the same.

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

The placement is important though, as explained in the article you linked, since the browser will "halt" (or "freeze") simultaneous downloads and rendering of the page when it encounters and loads the contents of a <script>tag. So it's probably best to let the browser render the page and apply CSS styles, and theninclude your .js. It will look smoother to the user.

但是,正如您链接的文章中所解释的那样,位置很重要,因为浏览器在遇到并加载<script>标记的内容时将“停止”(或“冻结”)页面的同时下载和呈现。因此,最好让浏览器呈现页面并应用 CSS 样式,然后将您的.js. 它对用户来说看起来更流畅。

Also, including the script at the bottom probably means right before you close the <body>tag.

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

回答by Rakesh Venkat

Along with the Performance aspect, you also need to be careful whenever you include the <script>tag inside the <head>tag.

除了性能方面,每当您在<script>标签中包含标签时,您还需要小心<head>

Let's consider the following example:

让我们考虑以下示例:

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

Here, notice that the script is loaded before the DOM (or the <p>tag) is loaded, which causes a failure in the script (Since the getElementById cant find the element with name 'demo').

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

In such cases you have to use the script within the body tag only.

在这种情况下,您必须仅在 body 标签中使用脚本。

Considering the other answers, its better to have the script always before the </body>tag as you never know whether the scripts that you would load externally have any such dependencies on your DOM.

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

Reference: Detailed problem description

参考:详细问题描述