Javascript 为什么要在body标记的末尾添加脚本

Javascript 为什么要在body标记的末尾添加脚本,javascript,html,css,web,pageload,Javascript,Html,Css,Web,Pageload,我知道这个问题被问了很多次,但我还没有找到答案。那么,为什么建议在body标记的末尾包含脚本以更好地渲染呢 从Udacity课程-在DOM和CSSOM就绪后开始渲染。JS是HTML解析阻塞,任何脚本都在CSSOM就绪后启动 因此,如果我们得到: <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1"> <tit

我知道这个问题被问了很多次,但我还没有找到答案。那么,为什么建议在body标记的末尾包含脚本以更好地渲染呢

从Udacity课程-在DOM和CSSOM就绪后开始渲染。JS是HTML解析阻塞,任何脚本都在CSSOM就绪后启动

因此,如果我们得到:

<html>
    <head>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>CRP</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <!-- content -->
        <script src="script.js"></script>
    </body>
</html>
如果脚本位于头部:

<html>
    <head>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>CRP</title>
        <link rel="stylesheet" href="styles.css">
        <script src="script.js"></script>
    </head>
    <body>
        <!-- content -->
    </body>
</html>

这个问题只涉及“同步”脚本(不带async/defer属性)。

从历史上看,脚本会阻止其他资源更快地下载。通过将它们放在底部,您的风格、内容和媒体可以更快地下载,从而提高性能


进一步阅读:和属性。

放置在脚本标记下面的图像将等待加载,直到JS脚本加载。通过将脚本标记放在底部,您可以首先加载图像,这样看起来页面加载速度更快。

在我看来,这是一种过时的做法。最近,JavaScript更倾向于将要求DOM出现在“DOMContentLoaded”事件侦听器中的任何代码分离开来。这不一定是所有的逻辑;许多代码可以在没有访问完整DOM的情况下进行初始化


的确,这会导致只检索脚本文件而不检索其他文件(例如,图像)的小时刻。通过添加
async
属性可以跳过这个小窗口,但即使没有它,我建议将脚本标记放在头部,以便浏览器尽快知道如何加载它们,而不是将它们(以及任何未来JS发起的请求)保存到最后。

我认为这取决于您的网站或应用程序。一些web应用程序基于JavaScript。那么,将其包含在页面底部是没有意义的,而是立即加载它。如果JavaScript只是将一些不太重要的特性添加到一些基于内容的页面中,那么最好在最后加载它。加载时间几乎相同,但用户会更早地看到重要部分(在页面完成加载之前)

这并不是说整个网站的加载速度更快,而是给用户一种网站加载速度更快的印象

例如: 这就是为什么基于Ajax的网站可以给人更快的印象。界面总是一样的。只有一些内容部分会改变。

对于任何给定的网页,都会从.html创建文档对象模型。CSS对象模型也是从.CSS创建的

我们还知道JS文件也会修改对象。当浏览器遇到标记时,当脚本运行时,DOM和CSS对象模型的创建会立即停止,因为它可以编辑所有内容。因此,如果js文件需要从任意一个树(DOM和CSS对象模型)中提取信息,它就没有足够的信息

因此,脚本srce通常位于主体的末尾,其中大多数树都已渲染

将JavaScript标记放在 关闭标记,而不是在HTML的部分中

原因是HTML从上到下加载。头部 首先加载,然后加载身体,然后加载身体内部的所有内容。如果我们 将我们的JavaScript链接放在标题部分,整个JavaScript 文件将在加载任何HTML之前加载,这可能会导致一些错误 问题

1.如果您的JavaScript中有代码,一旦 加载JavaScript文件时,实际上不会有任何HTML元素 它还没有生效,所以看起来 JavaScript代码不工作,您可能会出错。 2.如果你有很多JavaScript,它会明显减慢页面的加载速度 因为它在加载任何JavaScript之前加载所有JavaScript HTML。当您将JavaScript链接放在HTML的底部时 主体,它在加载任何JavaScript之前为HTML提供时间 加载,这可以防止错误,并加快网站响应时间

还有一件事:虽然最好在最后包含Javascript 将Javascript放在HTML的 HTML并不总是导致错误。在使用jQuery时,通常 将所有代码放入“document ready”函数中:

$(“document”).ready(函数(){//此处的代码})

这个函数的基本意思是,在 文档已准备就绪或已完全加载。这将防止任何错误, 但是它仍然可以减慢HTML的加载时间,这就是为什么 最好还是在所有HTML之后包含脚本


我注意到你说过。这仍然是真的,还是新的浏览器可以解决这个问题?@ChrisWalter过去与服务器的连接数量比较有限,随着HTTP2的出现,我们可以更快地下载所有数据。此外,脚本现在也可以延迟执行。因此,您指的是将延迟添加到脚本标记的末尾,如图所示:@ChrisWalter您应该查看和属性,最好不要通过w3schools。w3schools是我在Google上的第一次尝试,似乎已经明白了这一点:)我想在你的回答中补充一下,这些属性在Internet Explorer 10之前是不受支持的,所以仍然值得在HTML的末尾添加JavaScript。是的,但这取决于图像的数量。因为浏览器同时处理
src
,直到有一定数量的请求。还请注意,您可以始终为
标记使用
async
属性。建议浏览器在每个主机名上并行下载不超过两个组件@BuljanNice捕捉到的事实是,并非所有的JS都会对DOM对象进行残酷的处理。如果JS在正文末尾阻塞,则将呈现到该点的页面(如果CSSOM已准备就绪)。
<html>
    <head>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>CRP</title>
        <link rel="stylesheet" href="styles.css">
        <script src="script.js"></script>
    </head>
    <body>
        <!-- content -->
    </body>
</html>
CSSOM ready > JS execute > DOM ready > Rendering