什么是优点和缺点:将javascript放在头部,紧贴身体关闭之前


87

大多数javascript和Web开发书籍/文章都说您必须将CSS放在head标签中,并将javascript放在页面底部。

但是,当我打开著名网站的html源代码(例如此stackoverflow)时,我发现它们将一些js文件放在head标签中。

这两种方法的优缺点是什么,何时使用哪种方法?

针对同一问题发现了另一个问题: 我应该在哪里声明页面中使用的JavaScript文件?在<head> </ head>还是</ body>附近?



Answers:


63

摘自Yahoo的加速网站最佳实践

脚本引起的问题是它们阻止并行下载。HTTP / 1.1规范建议浏览器每个主机名并行下载最多两个组件。如果从多个主机名提供映像,则可以并行进行两个以上的下载。但是,在下载脚本时,即使使用不同的主机名,浏览器也不会启动任何其他下载。

在某些情况下,将脚本移到底部并不容易。例如,如果脚本使用document.write插入页面内容的一部分,则无法将其在页面中移至较低位置。可能还会存在范围界定问题。在许多情况下,有一些方法可以解决这些情况。

经常出现的另一种建议是使用延迟脚本。DEFER属性指示脚本不包含document.write,这是浏览器可以继续呈现的线索。不幸的是,Firefox不支持DEFER属性。在Internet Explorer中,该脚本可能会被延迟,但不会达到所需的程度。如果可以推迟脚本,则也可以将其移至页面底部。这将使您的网页加载更快。

因此,通常最好将它们放在底部。然而,它并不总是可能的,而且往往不会使多大的差别呢。


我有一个示例,该示例在画布上移动一个正方形,如果将javascript放在HTML的头部,它将不起作用。声明画布后,它必须在主体的底部。是否有这个原因,或者我如何将所有Javascript保留在文件的<head>部分中?
Doug Hauf 2014年

@DougHauf不知道我对此是否准确,但是您是否添加了DOMContentLoaded侦听器?我问是因为您的脚本是否在底部,并且可以很好地渲染到画布上;这是因为在尝试写入画布之前,画布已被加载到屏幕上。现在,如果将脚本放在标头中,则不会将其绘制到画布上,因为画布尚未存在。因此,如果添加侦听器,则会在加载画布后触发画布代码。
马修·达尔德

1
我不知道您引用的文档有多旧,但是在相当长的一段时间内Firefox一直支持defer属性
user2428118

谢谢,这对我有很大帮助
tonydeleon

31

正如其他人所说的那样,当您将javascript放在头部时,它会延迟页面的呈现,直到脚本被加载之后,这意味着页面可能需要更长的时间才能加载-尤其是在下载大型脚本文件时。

如果将脚本标签移动到页面的末尾,将确保浏览器在脚本标签之前下载图像和样式表,并且在脚本开始运行之前可能会呈现页面。这也意味着,如果您依靠脚本中的某些功能,则直到页面对用户可见后,此功能才可用。

如果要添加样式或元素(例如,使用某种形式的更丰富的编辑器切换文本字段),则对于用户来说,这将是闪烁可见的。

如果您要向元素添加点击事件,则只有在元素本身可见之后,它们才能被点击。

有时,这些问题需要您将脚本放在首位,而其他时候,将脚本放在底部会没事。

恕我直言(完全反对YSlow和很多聪明的人),您应该将脚本保留在head标签中,并且大部分时间都依赖于它们进行缓存。


9

通常,应将脚本引用放在页面底部。脚本不仅需要下载,还必须在释放块和页面进行渲染过程之前对其进行评估和执行。应该将诸如Modernizr之类的内容放在顶部,因为它会执行某些功能检测以及您可能需要的HTML5填充。

您想要尝试将脚本放置在页面底部的另一个原因是单点故障或SPOF。这是脚本调用超时或出于其他原因阻止页面执行的地方。第三方广告库等经常会发生这种情况。

是的,您可能需要更加认真地思考如何构建应用程序,但是对我来说,它很快变得非常自然。在过去的4年中,我使用底部的脚本构建了数百个Web应用程序,我可以分辨出两者之间的区别。我可能是500毫秒,可能是5000毫秒,但这很重要。


5

这确实取决于您的网站。如果要访问和调用体内的JavaScript函数,则必须在标头中引用它,以便对其进行加载。否则,如果仅在加载整个文档时才调用JavaScript,那么将JavaScript放在正文末尾是明智的。通过将.JS文件放在末尾,您可以加载整个页面,然后获取.JS文件。这样,用户将能够快速查看页面,并且在他/她熟悉页面时,已经下载了.JS文件。


4

加载页面之前,将评估头部中的所有javascript,这意味着页面感觉需要更长的加载时间。如果所有JavaScript都在末尾,则使事件正常工作会稍微困难一些,但是jQuery可以为您解决此问题。


2
您能否提及jQuery如何出于兴趣解决此问题?
马修·洛克

jQuery具有用于将处理程序绑定到事件的API
Draemon 2010年
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.