在 body 标记之前使用带有脚本的 'defer' 属性

Posted

技术标签:

【中文标题】在 body 标记之前使用带有脚本的 \'defer\' 属性【英文标题】:Using 'defer' attribute with scripts before the body tag在 body 标记之前使用带有脚本的 'defer' 属性 【发布时间】:2018-08-13 11:01:49 【问题描述】:

我在 Google 网页测试工具上运行我的网页,它建议我使用 'defer' 或 'async' 属性来摆脱渲染阻塞 JS 。我的 html 是这样的:

<!DOCTYPE html>
<html>

<head lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>My Page</title>
    <link href="https://mycdn.com/style.css" rel="stylesheet">
</head>

<body>
    <div id="app-container"></div>
    <script type="text/javascript" src="https://mycdn.com/shared.js"></script>
    <script type="text/javascript" src="https://mycdn.com/main.js"></script>
</body>

</html>

因为,我的脚本在“body”标签关闭之前被包含,而不是在“head”中,它们真的阻塞了吗?在解析结束的“html”之前不会发生绘画吗?

【问题讨论】:

Google 可能还会告诉您使用他们的压缩工具,而 MS 告诉您使用他们的压缩工具。屏蔽与否,他们只是希望您使用他们认为最佳的做法 @Huangism 你是说这个结构没有渲染阻塞脚本? 如果你的页面只有一个这样的容器,那真的没有太大区别。但是使用defer没有错 我知道我可以使用 defer 并且不会有什么不同。我实际上是想了解这种结构是否真的会阻止渲染。 @Huangism 它让你感觉加载速度更快,但它可能会阻止用户交互你可以看看***.com/questions/30653081/…你的内容将更早地对用户可见,所以底部的脚本允许这样做,在我的观点是,它不会阻止你的 dom 内容,但是如果你在 js 中有交互,那么显然只有在 js 加载完成后才会起作用 【参考方案1】:

使用 async 或 defer 或将脚本移动到文件底部并不总是适用于不同的浏览器,加载外部脚本的一种推荐方法是按以下方式加载它,将这段代码放在正文标签结束。

<script type="text/javascript">
  function downloadJSAtOnload()
    var element = document.createElement("script");
    element.src = "defer.js"; // Replace "defer.js" with your url or filename
    document.body.appendChild(element);
  
  if (window.addEventListener) window.addEventListener("load", downloadJSAtOnload, false);
  else if(window.attachEvent) window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>

See here for more.

【讨论】:

@time-han 我真正想知道的是,如果使用我的 HTML,底部的脚本会阻塞。

以上是关于在 body 标记之前使用带有脚本的 'defer' 属性的主要内容,如果未能解决你的问题,请参考以下文章

js的延迟脚本----defer与异步脚本----async

JavaScript 的 defer 与 async

javascript笔记

区分defer和async

在开始 <body> 标记之后立即放置一个脚本

在底部渲染阻塞延迟与移动脚本