我应该在HTML标记中放置<script>标记?
将JavaScriptembedded到HTML文档中时,放置<script>
标记和包含JavaScript的适当位置在哪里? 我似乎还记得,你不应该把它们放在<head>
部分,但是放在<body>
部分的开头也是不好的,因为在页面完全呈现之前JavaScript将被parsing(或类似的东西)。 这似乎将<body>
部分的末尾作为<script>
标记的逻辑位置。
那么,在哪里放置<script>
标签呢?
(这个问题引用了这个问题 ,其中提到JavaScript函数调用应该从<a>
标签移动到<script>
标签,我特别使用jQuery,但更一般的答案也是适当的。
以下是浏览器加载带有<script>
标签的网站时发生的情况:
- 取HTML页面(例如index.html)
- 开始parsingHTML
- parsing器遇到引用外部脚本文件的
<script>
标记。 - 浏览器请求脚本文件。 同时,parsing器会阻止并parsing页面上的其他HTML。
- 一段时间后,脚本被下载并随后执行。
- parsing器继续parsingHTML文档的其余部分。
步骤4导致不良的用户体验。 你的网站基本上停止加载,直到你下载了所有的脚本。 如果有一件事,用户讨厌它正在等待一个网站加载。
为什么这会发生?
任何脚本都可以通过document.write()
或其他DOM操作来插入自己的HTML。 这意味着parsing器必须等到脚本被下载并执行之后才能安全地parsing文档的其余部分。 毕竟,脚本可以在文档中插入自己的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, ie when the document has been parsed document.getElementById("user-greeting").textContent = "Welcome back, Bart"; });
因为你的浏览器不知道我的script.js不会修改文档,直到它被下载和执行,parsing器停止parsing。
陈旧的build议
解决这个问题的旧方法是把<script>
标签放在<body>
的底部,因为这样可以确保parsing器不会被阻塞,直到最后。
这种方法有其自身的问题:浏览器不能开始下载脚本,直到整个文档被parsing。 对于大型脚本和样式表的大型网站,能够尽快下载脚本对性能非常重要。 如果您的网站在2秒内未加载,则会转到其他网站。
在最佳解决scheme中,浏览器将尽快下载脚本,同时parsing文档的其余部分。
现代的方法
今天,浏览器支持脚本的async
和defer
属性。 这些属性告诉浏览器在下载脚本时继续parsing是安全的。
asynchronous
<script type="text/javascript" src="path/to/script1.js" async></script> <script type="text/javascript" src="path/to/script2.js" async></script>
具有asynchronous属性的脚本是asynchronous执行的。 这意味着脚本在下载后立即执行,同时不会阻塞浏览器。
这意味着可以在脚本1之前下载并执行脚本2。
根据http://caniuse.com/#feat=script-async,90%的浏览器都支持这个function。;
延缓
<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)。 这也不会阻止浏览器。
与asynchronous脚本不同,延迟脚本仅在整个文档被加载后执行。
根据http://caniuse.com/#feat=script-defer,90%的浏览器都支持这个function。; 92%至less部分支持。
浏览器兼容性的重要注意事项:在某些情况下,IE <= 9可能会按顺序执行延迟脚本。 如果您需要支持这些浏览器,请先阅读本文 !
结论
目前最先进的技术是将脚本放在<head>
标签中,并使用async
或defer
属性。 这可以让您的脚本尽快下载,而不会阻塞您的浏览器。
好的是,你的网站仍然应该正确加载20%的不支持这些属性的浏览器,同时加快其他80%。
就在结束标签之前,如上所述
http://developer.yahoo.com/performance/rules.html#js_bottom
把脚本放在底部
脚本造成的问题是阻止并行下载。 HTTP / 1.1规范build议浏览器每个主机名并行下载至less两个组件。 如果您从多个主机名提供图像,则可以同时进行两个以上的下载。 然而,当脚本正在下载时,浏览器将不会启动任何其他下载,即使在不同的主机名上。
非阻塞脚本标签可以放在任何地方:
<script src="script.js" async></script> <script src="script.js" defer></script> <script src="script.js" async defer></script>
-
async
脚本将在可用时立即执行 - 当文档完成parsing时,将执行
defer
脚本 - 如果asynchronous不受支持,
async defer
脚本将回退到延迟行为
这样的脚本将在文档准备好后asynchronous执行,这意味着你不能这样做:
<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 -->
话虽如此,asynchronous脚本提供了这些优势:
- 并行下载资源 :
浏览器可以同时下载样式表,图像和其他脚本,无需等待脚本下载和执行。 - 来源订单独立性 :
您可以将脚本放置在头部或身体中,而无需担心阻塞(如果使用CMS,则可用)。 执行顺序依然很重要。
通过使用支持callback的外部脚本可以规避执行顺序问题。 许多第三方JavaScript API现在支持非阻塞执行。 以下是asynchronous加载Google Maps API的示例。
标准的build议,由Yahoo! 卓越的性能团队,将<script>
标签放在文档主体的末尾,以防止页面的渲染。
但有一些更新的方法提供更好的性能,我在这里复制另一个答案 :
Steve Souders(客户端性能专家)提供了一些很棒的幻灯片 :
- 不同的技术来并行加载外部JavaScript文件
- 它们对加载时间和页面渲染的影响
- 浏览器显示什么样的“进行中”指标(例如状态栏中的“加载”,沙漏鼠标光标)。
如果你正在使用JQuery,那么把JavaScript放在最好的位置,并使用$(document).ready()
来确保在执行任何函数之前正确加载了东西。
在旁注:我喜欢所有我的脚本标签在<head>
部分,因为这似乎是最干净的地方。
<script src="myjs.js"></script> </body>
script标签应该总是在bodyclosures之前使用,或者在HTML文件中使用Bottom 。
那么你可以在加载js文件之前先看到页面的内容。
检查这是否需要: http : //stevesouders.com/hpws/rule-js-bottom.php
XHTML不会validation脚本是否在head元素以外的任何地方。 事实certificate它可以在任何地方。
你可以推迟执行类似jQuery的东西,所以它放在哪里并不重要(除了在parsing过程中的小性能击中)。
传统的(被广泛接受的)答案是“在底部”,因为那么整个DOM将在任何事情能够开始执行之前被加载。
有各种各样的原因,从可用的实践开始,故意开始执行页面onload事件。
根据脚本及其用法,尽可能最好(就页面加载和渲染时间而言)可能不是使用传统的<script> -tag本身,而是dynamic地触发asynchronous加载脚本。
有一些不同的技术,但最直接的是当window.onload事件被触发时使用document.createElement(“脚本”)。 然后脚本在页面本身已经被渲染时被首先加载,因此不影响用户等待页面出现的时间。
这自然要求脚本本身不需要渲染页面。
有关更多信息,请参阅由Steve Souders(YSlow的创build者,但现在在Google)的Couplingasynchronous脚本 。
取决于,如果你正在加载一个必要的脚本来设置你的页面风格/在你的页面中使用动作(比如点击一个button),那么你最好把它放在顶部。 如果你的样式是100%的CSS,并且你有所有button动作的后备选项,那么你可以把它放在底部。
或者最好的东西(如果这不是一个问题),你可以做一个模式加载框,把你的JavaScript放在你的页面的底部,并使其消失当你的脚本的最后一行被加载。 这样可以避免用户在加载脚本之前使用页面中的操作。 而且还避免了不恰当的造型。
脚本块加载DOM,直到它被加载并执行。
如果你把脚本放在<body>
的末尾,所有的DOM都有加载和渲染的机会(页面将“更快地显示”)。 <script>
将有权访问所有这些DOM元素。
另一方面,在<body>
开始或之后放置它将执行脚本(仍然没有DOM元素)。
你包括jQuery,这意味着你可以把它放在任何你想要的地方并使用.ready()
-
如果您仍然关心IE 10中的支持和性能,最好总是让脚本标记HTML主体的最后一个标签。 这样,你可以确定DOM的其他部分已经被加载,你不会阻塞和渲染。
-
如果您对IE <10不再太在意,您可能希望将脚本放在文档的头部,并使用
defer
来确保它们只在加载DOM后运行(<script type="text/javascript" src="path/to/script1.js" defer></script>
)。 如果你仍然希望你的代码在IE 10中工作,不要忘记把你的代码封装在一个window.onload
,尽pipe!
我认为这取决于网页的执行。 如果您要显示的页面无法正确显示,请先加载JavaScript,然后再加载JavaScript文件。 但是,如果您不显示最初下载的JavaScript文件就可以显示/呈现网页,那么您应该将JavaScript代码放在页面底部。 因为它会模拟一个快速的页面加载,并从用户的angular度来看,似乎该页面加载速度更快。
您可以将<script>
引用的大部分放在<body>
,
但是,如果页面上有使用外部脚本的活动组件,
那么他们的依赖(js文件)应该在这之前(最好是头标记)。
编写JavaScript
代码的最好的地方就是在文档代码的末尾加上标签后加载文档然后执行js代码。 如果你写的JQuery
代码写
$(document).ready (function{ //your code here });
在HTML文件的末尾,以免在执行时在浏览器中加载Html文件。
在HTML之后包含脚本对我来说更有意义。 因为大部分时间我都需要在我执行脚本之前加载Dom。 我可以把它放在头标签,但我不喜欢所有的文件加载监听器开销。 我希望我的代码简短而又甜美,而且易于阅读。
我听说老版本的Safari浏览器在头标以外添加脚本时很夸张,但我说谁在乎。 我不知道有人使用那个废话。
好的问题的方式。
你可以放置你想要的脚本,一个不比另一个练习更好。
情况如下:
页面加载是线性的,“自顶向下”,所以如果你把脚本放在头部,确保它在所有事情之前开始加载,现在,如果你把它放在身体里面混入代码会导致页面加载不美观。
确定好的做法不取决于哪里。
为了支持你,我会提到以下几点:
你可以放置:
并且页面将线性加载
页面与其他内容asynchronous加载
页面的内容将在加载完成前后加载脚本加载
这里的好做法是什么时候执行每个?
我希望我已经有所帮助,只要回答我这个问题。