【问题标题】:Why scripts at the end of body tag为什么在body标签末尾写脚本
【发布时间】:2015-08-19 14:38:41
【问题描述】:

我知道这个问题被问了很多次,但我没有找到答案。那么为什么建议在正文标签的末尾包含脚本以获得更好的渲染效果呢?

来自 Udacity 课程 https://www.udacity.com/course/ud884 - 在 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>

CRP 将是:

CSSOM ready > JS execute > DOM ready > Rendering

如果脚本在前面:

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

CRP 是一样的:

CSSOM ready > JS execute > DOM ready > Rendering

这个问题只是关于“同步”脚本(没有 async/defer 属性)。

【问题讨论】:

  • 渲染不是一次完成的,而是逐步完成的。如果 JS 在正文末尾阻塞,则将呈现该点之前的页面(如果 CSSOM 已准备好)。

标签: javascript html css web pageload


【解决方案1】:

从历史上看,脚本会阻止其他资源更快地下载。通过将它们放在底部,您的样式、内容和媒体可以更快地下载,从而感知性能得到改善。

延伸阅读:asyncdefer 属性。

【讨论】:

  • 我注意到你曾经说过。这仍然是真的,还是新的浏览器可以解决这个问题?
  • @ChrisWalter 过去与服务器的连接数量更加有限,随着 HTTP2 的到来,我们可以更快地获取所有数据。此外,这些天也可以推迟脚本的执行。
  • 所以您指的是在脚本标签的末尾添加延迟,如下所示:w3schools.com/tags/att_script_defer.asp
  • @ChrisWalter 您应该同时查看asyncdefer 属性,并且最好不要通过w3schools。
  • W3Schools 是我在 Google 上的第一次点击,并且似乎明白了这一点:) 我想在您的答案中补充说,直到 Internet Explorer 10 才支持这些属性,所以仍然值得添加你的 JavaScript 到你的 HTML 的末尾。
【解决方案2】:

在我看来,这是一种过时的做法。最近,JavaScript 更倾向于将需要 DOM 存在的任何代码分离到“DOMContentLoaded”事件侦听器中。这不一定是所有逻辑;许多代码无需访问完整的 DOM 即可初始化。

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

【讨论】:

  • 很好的发现,实际上并不是所有的 JS 都对 DOM 对象做残酷的事情。
【解决方案3】:

最好将 JavaScript 标记放在 结束标记而不是 HTML 部分。

这样做的原因是 HTML 从上到下加载。头部 首先加载,然后是身体,然后是身体内的一切。要是我们 把我们的 JavaScript 链接放在 head 部分,整个 JavaScript 文件将在加载任何 HTML 之前加载,这可能会导致一些 问题。

1.如果您的 JavaScript 中有代码会立即更改 HTML JavaScript 文件加载,实际上不会有任何 HTML 元素 还可以影响它,所以看起来好像 JavaScript 代码不起作用,您可能会遇到错误。 2.如果你有很多 JavaScript,它会明显减慢页面的加载速度 因为它会先加载所有的 JavaScript,然后再加载任何 HTML。当您将 JavaScript 链接放在 HTML 的底部时 正文,它让 HTML 有时间在任何 JavaScript 之前加载 加载,可以防止错误,并加快网站响应时间。

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

$("document").ready(function(){ // 你的代码在这里 });

这个函数基本上是说,不要运行里面的任何代码,直到 文档已准备好或已满载。这将防止任何错误, 但它仍然会减慢 HTML 的加载时间,这就是为什么 最好还是在所有 HTML 之后包含脚本。

【讨论】:

    【解决方案4】:

    位于脚本标签下方的图像将等待加载,直到 JS 脚本加载。通过将脚本标签放在底部,您首先加载图像,从而使页面加载速度更快。

    【讨论】:

    • 是的,但这取决于图像的数量。由于浏览器同时处理src 直到一些请求。另请注意,您始终可以将async 属性用于&lt;script&gt; 标记。
    • HTTP/1.1 specification 建议浏览器每个主机名并行下载不超过两个组件。 @RokoC.Buljan
    【解决方案5】:

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

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

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

    【讨论】:

      【解决方案6】:

      This was an extremely useful link. 对于任何给定的网页,文档对象模型都是从 .html 创建的。 CSS 对象模型也是从 .css 创建的。

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

      因此,脚本 srces 通常位于大多数树已经渲染的主体的末尾。

      【讨论】:

        猜你喜欢
        • 2014-10-09
        • 2022-12-05
        • 2013-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多