我应该在哪里放置标签的HTML标记?

问题描述 投票:1313回答:20

当一个HTML文档中嵌入的JavaScript,这里是把<script>标签和包含的JavaScript适当的地方吗?我似乎记得,你是不是应该把这些在<head>部分,但在<body>节的开头将是坏的,也因为JavaScript的将收到的页面完全呈现被解析(或类似的东西)。这似乎离开<body>节结束,作为<script>标签逻辑的地方。

所以,哪里是把<script>标签正确的地方?

(这个问题引用this question,其中有人认为JavaScript函数调用应该从<a>标签移到<script>标签。我专门使用jQuery,但更普遍的答案也是合适的。)

javascript jquery html
20个回答
1718
投票

下面是当浏览器加载上有一个<script>标签的网站,会发生什么:

  1. 取HTML页面(例如,index.html)
  2. 开始解析HTML
  3. 解析器遇到<script>标签引用外部脚本文件。
  4. 浏览器请求该脚本文件。同时,分析器块和停止解析你的页面上的其他HTML。
  5. 一段时间之后,脚本下载并随后执行。
  6. 解析器继续解析HTML文档的其余部分。

第4步会导致不良的用户体验。您的网站基本上停止装载,直到你已经下载的所有脚本。如果有一件事是用户讨厌它等待网站加载。

为什么这甚至会发生?

任何脚本可以插入通过document.write()或其他DOM操作自己的HTML。这意味着解析器必须等待,直到脚本已被下载和执行,才可以安全地解析文档的其余部分。毕竟,脚本可能在文档中插入自己的HTML。

然而,大多数JavaScript开发人员不再操作DOM文档加载时。相反,他们等到文档修改之前被加载。例如:

<!-- index.html -->
<html>
    <head>
        <title>My Page</title>
        <script type="text/javascript" src="my-script.js"></script>
    </head>
    <body>
        <div id="user-greeting">Welcome back, user</div>
    </body>
</html>

使用Javascript:

// my-script.js
document.addEventListener("DOMContentLoaded", function() { 
    // this function runs when the DOM is ready, i.e. when the document has been parsed
    document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});

由于您的浏览器不知道我的-的script.js不走,直到它已被下载和执行修改文档,解析器解析停止。

陈旧推荐

旧的方法来解决这个问题是把<script>标签在你<body>的底部,因为这可以确保解析器没有被阻塞,直到最后一刻。

这种方法有其自身的问题:直到整个文档进行分析,浏览器无法开始下载该脚本。对于有大量的脚本和样式表,能够尽快下载脚本较大的网站是非常重要的性能。如果你的网站没有在2秒钟内加载,人们会去别的网站。

在一个最佳的解决方案,浏览器将开始尽快下载你的脚本,而在同一时间解析文档的其余部分。

现代的方法

今天,浏览器支持asyncdefer上的脚本属性。这些属性告诉浏览器是安全的同时,将下载的脚本来继续分析。

async

<script type="text/javascript" src="path/to/script1.js" async></script>
<script type="text/javascript" src="path/to/script2.js" async></script>

与异步特性的脚本是异步执行的。这意味着脚本,只要它的下载执行,同时不阻止浏览器。 这意味着,它可能脚本2下载和脚本1之前执行。

http://caniuse.com/#feat=script-async,所有的浏览器的94.57%支持这一点。

defer

<script type="text/javascript" src="path/to/script1.js" defer></script>
<script type="text/javascript" src="path/to/script2.js" defer></script>

与defer属性脚本顺序执行(即第一脚本1,脚本然后2)。这也不会阻止浏览器。

与异步脚本,推迟整个文档加载后脚本才会执行。

http://caniuse.com/#feat=script-defer,所有的浏览器的94.59%支持这一点。 94.92%的支持它至少部分。

上的浏览器兼容性的重要说明:在某些情况下IE <= 9可以执行延期脚本乱序。如果您需要支持这些浏览器,请先阅读this

Conclusion

当前国家的最先进的是把脚本在<head>标签和使用asyncdefer属性。这使你的脚本不尽快阻止浏览器下载。

好消息是,你的网站还是应该正确加载上同时加快其他94%不支持这些属性的浏览器的6%。


2
投票

根据不同的脚本和它的使用最可能(在页面加载和渲染时间方面)可以是不使用常规的<SCRIPT> -tag本身,而是动态地触发脚本的加载异步。

有一些不同的技术,但最直接的方法是使用使用document.createElement(“脚本”)在触发window.onload事件。然后,当页面本身已经呈现,从而不影响用户必须等待页面出现的时候脚本加载第一。

这自然要求该脚本本身是不需要的页面的渲染。

欲了解更多信息,请参见由史蒂夫Souders的(YSlow的创造者,但现在在谷歌)后Coupling async scripts


2
投票
  • 如果你仍然非常关心支持和性能在IE <10,这是最好的总是使你的脚本标记您的HTML身体的最后一个标签。这样的话,你肯定的是,DOM的其余部分已被加载,你会不会阻止和渲染。
  • 如果你不关心太多了关于IE <10,你可能想要把你的脚本在文档的头部和使用defer,以确保他们只有在你的DOM已经被加载(<script type="text/javascript" src="path/to/script1.js" defer></script>)运行。如果您仍然希望您的代码在IE中<10工作,不要忘了换你的代码在window.onload甚至,但!

2
投票

末包括脚本主要是用在内容/风格的网站将首先被显示。

包括头部脚本加载早期脚本,并且可以在整个网站的加载之前使用。

如果脚本是在最后输入的验证将只是整个风格和设计,这是不赞赏的快速响应网站的加载后发生。


1
投票

要看,如果要加载一个脚本,有必要风格你的网页/在你的页面(如点击按钮)使用行为,那么你最好将它放在上面。如果你的风格是100%的CSS,你有按钮操作的所有后备选项,那么你可以将其放置在底部。

或者,最好的事情(如果这不是一个问题)是你可以做一个模式加载中,将你的JavaScript在页面的底部,并在你的脚本的最后一行被加载它消失。这样,你能避免使用在你的页面动作加载的脚本之前用户。还可以避免不当的造型。


1
投票

脚本块DOM负载,直到它的加载和执行。

如果您在<body>所有DOM的结束放置脚本有机会来加载和渲染(页面将“显示”更快)。 <script>将有机会获得所有这些DOM元素。

在另一方面把它放在后<body>启动或以上将执行脚本(其中还是有没有DOM元素)。

你是包括jQuery的,这意味着只要你愿意,你可以把它和使用.ready()


1
投票

我认为这取决于在网页上执行。如果不能没有加载JavaScript正确显示你要显示的第一页,那么你应该首先包含JavaScript文件。但是如果你可以显示/渲染网页不用最初下载JavaScript文件,那么你就应该把JavaScript代码在页面的底部。因为它会模仿迅速页面加载,并从一个角度用户的角度来看它会看起来像页面加载速度更快。


1
投票

你可以把最<script>引用在<body>结束, 但是,如果您的网页上的活跃组件,这些组件使用外部脚本, 那么它们的依赖(js文件)应该来之前(最好在头标记)。


0
投票

最好的地方放qazxsw POI标签关闭qazxsw POI标签之前,这样的下载和执行它不会阻止浏览器解析HTML文件,

还加载js文件外都有它自己的喜欢它的优势会被浏览器缓存,可以加快页面加载时间,它分隔的HTML和JavaScript代码,并帮助管理代码库更好。

但现代浏览器还支持像<script></body>其他一些最佳的方式来加载外部async文件。

异步和推迟

通常HTML页面执行由行开始行。当遇到外部JavaScript元素,HTML解析停止,直到JavaScript是下载并准备执行。这种正常的页面执行可以使用deferjavascript属性进行更改。

defer

当使用defer属性,JavaScript是用HTML解析并行下载,但完整的HTML解析完成后,才将被执行。

async

Defer

当使用异步属性,JavaScript是只要遇到脚本解析HTML一起下载,下载后,它会被异步(并行)执行。

<script src="/local-js-path/myScript.js" defer></script>

当要使用的属性

  • 如果你的脚本是独立于其他脚本,并且是模块化的,使用Async
  • 如果要加载SCRIPT1和SCRIPT2与<script src="/local-js-path/myScript.js" async></script> ,都将运行 与HTML解析平行一起,只要他们下载 并可用。
  • 如果你的脚本依赖于另一个脚本,然后使用async两个:
  • 当SCRIPT1和SCRIPT2与async该顺序装入,则SCRIPT1保证第一执行,
  • 再经过充分执行SCRIPT1 SCRIPT2将执行。
  • 要做到这一点,如果SCRIPT2取决于SCRIPT1。
  • 如果你的脚本是足够小,由式defer的另一个脚本依赖然后没有任何属性使用您的脚本,并把它上面的所有defer脚本。

参考:async


-1
投票

它更有意义,我包括HTML后的脚本。因为大部分的时间我需要的大教堂前,我执行我的脚本加载。我可以把它的头标记,但我不喜欢所有的文档放入听者的开销。我想我的代码是短期和甜,易于阅读。

我听说head标签之外添加脚本时,Safari浏览器的旧版本是quarky但是我说谁在乎。我不使用旧垃圾你知道任何人。

顺便说一下这个问题问得好。


-1
投票

在HTML文档的结尾

因此,它不会在执行时实现HTML文档的加载在浏览器中。


230
投票

就在结束标记之前,如前所述上

http://developer.yahoo.com/performance/rules.html#js_bottom

把脚本在底部

造成脚本的问题是,他们阻止并行下载。的HTTP / 1.1规范建议的浏览器下载不超过两种组分在每主机名平行。如果您从多个主机名服务于您的图片,你可以并行地出现两个以上的下载量。尽管脚本下载,然而,浏览器将不会启动任何其他下载,甚至在不同的主机名。


-2
投票

写在文件代码标签之后结束你的async代码最好的地方,然后加载该文件执行js代码。如果你所写的代码knowledgehills.com

JavaScript

-6
投票

你可以把你想要的脚本和一个并不比另一个更好的做法。

情况如下:

页面加载线,“自上而下”的,所以,如果你把脚本的头部确保它开始一切之前加载,现在,如果你把它与代码混合会导致页面体内加载一个难看的方式。

确定好的实践不依赖于何处。

支持你,我会提到以下几点:

你可以把:

并且页面加载线性

页与其他内容异步加载

该页面的内容将装载完毕之前和之后加载脚本加载

好的做法这里会,何时会实现每一个?

我希望我一直乐于助人,什么都只是回答我这个问题。


69
投票

非阻塞脚本标记可以直接放在任何地方:

<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
  • async脚本将被异步只要它是可用执行
  • 当文档已经完成解析执行defer脚本
  • async defer脚本回落到延迟的行为,如果不支持异步

此类脚本将被异步执行/文件准备好了,这意味着你不能做到这一点后:

<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
  * might throw "jQuery is not defined" error
  * defer will not work either
-->

或这个:

<script src="document.write(something).js" async></script>
<!--
  * might issue "cannot write into document from an asynchronous script" warning
  * defer will not work either
-->

或这个:

<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
  * might throw "jQuery is not defined" error (no guarantee which script runs first)
  * defer will work in sane browsers
-->

或这个:

<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
  * might not locate #header (script could fire before parser looks at the next line)
  * defer will work in sane browsers
-->

话虽如此,异步脚本提供了以下优点:

  • 资源并行下载: 浏览器可以下载样式表,图片和其他脚本并行而不等待脚本下载和执行。
  • 来源顺序无关: 您可以将内部头部或身体的脚本,而无需担心阻塞(有用的,如果您使用的是CMS)。执行顺序仍然很重要,但。

可以通过使用支持回调外部脚本来规避执行顺序的问题。许多第三方的JavaScript API现在支持无阻塞执行。下面是loading the Google Maps API asynchronously的一个例子。


37
投票

该标准建议,由雅虎推广卓越的性能团队,是把<script>标签在文档主体的末尾,以便它们不会阻塞页面的渲染。

但也有提供更好的性能,如关于谷歌Analytics(分析)JavaScript文件的加载时间this answer描述的一些较新的方法:

还有一些great slides由史蒂夫Souders的(客户端性能专家)约:

  • 不同的技术来负载并联外部JavaScript文件
  • 他们的加载时间和网页渲染效果
  • 什么样的“进行中”的指标浏览器显示(例如,在状态栏“加载”,沙漏形鼠标光标)。

23
投票

如果您正在使用JQuery然后把javascript的,无论你找到它最好使用$(document).ready()以确保事情执行任何功能之前正确加载。

在一个侧面说明:我喜欢在<head>节我所有的脚本标记的,这似乎是最干净的地方。


10
投票

如果脚本比头元素内的任何地方其他XHTML不会验证。 原来它可以无处不在。

你可以像jQuery的推迟执行,以便在那里它被放置(除了一个小的性能分析过程中命中)也没关系。


10
投票
<script src="myjs.js"></script>
</body>

脚本标签应该是身体在HTML文件或接近底部,使用前始终。

那么你就可以看到页面的内容加载第一js文件之前。

勾选此要求:http://stevesouders.com/hpws/rule-js-bottom.php


8
投票

在2019年的现代方法是使用ES6模块类型的脚本。

<script type="module" src="..."></script>

默认情况下,模块异步加载和延迟执行。即你可以在任何地方放置它们,它们将在并行加载,当网页加载完成执行。

脚本和模块之间的差异描述如下:

https://stackoverflow.com/a/53821485/731548

一个模块相比,脚本执行被描述如下:

https://developers.google.com/web/fundamentals/primers/modules#defer

支持如下所示:

https://caniuse.com/#feat=es6-module


6
投票

传统的(和广泛接受的)回答是“底部”,因为那时整个DOM将已经什么都可以开始执行之前加载。

有异议者,由于种种原因,与现有的实践出发,故意开始执行与页面onload事件。

© www.soinside.com 2019 - 2024. All rights reserved.