延迟属性 (Chrome)

IT技术 javascript google-chrome attributes
2021-03-12 23:44:58

Chrome 对我来说一直是 Web 标准的参考,遗憾的是不支持defer,IE 从 5.5 版开始支持它。为什么 ?

js.js

document.getElementById ("hi").innerHTML = "Hi :)";

HTML

<!DOCTYPE html>
<html>
    <head>
        <meta charset = "utf-8">
        <script defer="defer" src="js.js"></script>
        <title>Hi</title>
    </head>
    <body>
        <div id="hi"></div>
    </body>
</html>
3个回答

什么deferasync意味着什么呢?

默认情况下,<script src=...></script>标签是邪恶的!浏览器必须停止解析 HTML,直到下载并执行脚本(因为脚本可能会调用document.write(...)或定义以后的脚本所依赖的全局变量)。这意味着脚本标签之后的任何图像和样式表在脚本完成下载和执行之前不会开始下载。外部脚本通常会使 Web 加载更慢,这就是 NoScript 变得如此流行的原因。

微软推出defer来解决这个问题。如果你使用<script defer src=...></script>,你保证不打电话document.write(...)一个defer外部脚本就会立即开始下载,但不会执行,直到页面之后被渲染。页面呈现后,所有defer脚本都按照声明的顺序执行。并非所有浏览器都实现defer了。

HTML5 引入了async可以在任何时间执行属性——可能在页面完成解析之前,甚至在其他defer/async仍在下载的脚本之前但是使用多个async脚本比较困难,因为它们的执行顺序没有保证。就像defer,并非所有浏览器都实现async了。

执行完所有deferasync脚本之后,将触发DOMContentLoadedload事件。

简史deferasync

  • 1997 IE 4 引入defer.
  • 1998 HTML 4 规范提到了defer,但不幸的是它没有准确说明defer脚本执行的时间(全部按顺序?之前onload?)。因此,没有其他浏览器实施,defer因为没有人想对 IE 的行为进行逆向工程或破坏可能取决于 IE 特性的脚本。例如,请参阅Mozilla 功能请求)。
  • 2006 HTML5 草案最终描述了实现所需的细节deferdefer所有脚本都应该在解析页面其余部分之后和之前按顺序执行onload它还引入async了指定可以在下载时执行的脚本,而不必相互等待。不幸的是,HTML5 不允许内联defer脚本与 IE 相矛盾打破了所有defer脚本按顺序执行的不变性(如果某些defer脚本src具有内联内容,而某些脚本具有内联内容)。
  • 2009 Gecko 1.9.1 (Firefox 3.5)支持defer.
  • 2010-01 Gecko 1.9.2 (Firefox 3.6)支持async.
  • 2010-09deferasync签入 Webkit您应该很快就会在 Chrome 和 Safari 中看到它(它已经在 Chrome 开发者频道中,但它有点问题)。
  • 我们仍在等待 Opera 的实现deferasyncIE 的实现async

那么 Web 开发人员应该使用什么?

目前没有单一的规则可以遵循。您必须为访问您网站的浏览器组选择最能平衡简单性、页面呈现延迟和脚本执行延迟的解决方案。

  • 正如其他人指出的那样,在脚本执行之前呈现页面的最简单方法是将脚本放在页面底部。但是,如果脚本是必不可少的,或者网页包含大量 HTML,那么您应该将脚本放在页面的更高位置。
  • 如果您的脚本是独立的并且您的客户使用 IE 或新版本的 Firefox,请使用<script async defer src=...></script>:这允许呈现与 IE 和最新的 HTML5 浏览器的脚本下载并行继续,但会导致 HTML5 之前的浏览器(包括所有版本的 Opera)被阻止.
  • 如果一个外部脚本依赖于另一个,标记它们defer(但不是async),它们将按照它们声明的顺序执行(除了IE<=9 在某些条件下可以乱序执行它们)。同样,这允许在 IE 和支持 HTML5 的 Gecko/Webkit 中的脚本下载的同时继续进行渲染,但较旧的浏览器和 Opera 会受到影响。defer即使脚本位于页面底部,也最好使用这些脚本,以便它们彼此并行下载。
  • 永远不要defer用于内联脚本,因为 HTML5 草案已经取消了执行顺序保证。
  • 如果您的受众包括许多 Opera 或老 Firefox/Safari 用户,以下代码段将在大多数 HTML5 之前的浏览器(IE、Webkit,需要测试旧版 Firefox)上解析文档后执行脚本,而最新的支持 HTML5 的浏览器启动立即下载但不会因为该async属性而阻止执行脚本换句话说,大多数较旧的浏览器将其视为页面底部的脚本,而最新的浏览器会识别async. 但是 Opera 用户得到了两全其美的结果,因为 Opera 立即开始执行并且不理解async. 这是Google Analytics在许多网页上为海胆推荐模式

片段:

<script>
(function() {
  var script = document.createElement('script');
  script.src = '...';
  script.async = true;
  var s = document.getElementsByTagName('script')[0];
  s.parentNode.insertBefore(script, s);
})();
</script>
  • 如果另一个脚本依赖于要加载的第一个脚本,那么您可以使用与上面相同的模式,但在执行第二个脚本之前先侦听第一个脚本元素的 onload 事件。有关如何等待另一个脚本加载的信息,请参阅LABjs 示例
  • 如果您有多个具有复杂依赖关系的脚本,请使用LAB.jsYUI Loader使它们并行下载并以某种有效顺序执行。
  • 如果您使用的是流行的库,例如 jQuery,请考虑使用Google 的副本而不是您自己的副本,以增加浏览器已经缓存它的可能性。

更新:如果您将脚本拆分为module并希望提高性能,我建议您阅读Steve Souder 所著Even Faster Web Sites的“耦合异步脚本”一章它包含的提示/技巧不仅可以控制执行顺序,还可以延迟脚本解析以提高性能。

我从这里得到了这个:“即使脚本位于页面底部,使用 defer 也是一个好主意,以便它们彼此并行下载。” 重要的一个。
2021-04-23 23:44:58
注意这个问题:github.com/h5bp/lazyweb-requests/issues/42 TL;DR,defer由于一个错误,不保证 IE <= 9 中的顺序,所以“如果一个外部脚本依赖另一个”并且你使用defer,您可能仍然有问题。
2021-05-13 23:44:58

defer仅受 Internet Explorer 支持。你不需要依赖它。还有其他方法可以获得相同的效果,例如将您的脚本放在页面末尾的</body>标签之前,正如其他人所指出的那样。

defer 的目的是告诉外部链接的脚本等待页面加载完成,直到它运行。同样的事情可以通过良好的不显眼的 JavaScript 方法来完成,这些方法通常包含阻止脚本在 DOM 完成加载之前执行的代码。

defer 的优点是与 Internet Explorer 相关联,因为该浏览器是唯一支持 defer 属性的浏览器。因此,如果您需要一个仅在 IE 中运行的快速脚本,并且您不介意整个页面是否在开始执行之前加载,那么只需在您的标签中添加 defer="defer" 即可快速解决这个问题问题。修复 IE6 中的透明 PNG 问题是 defer 的一种可能的实际用途。

在使用针对 IE 专用脚本的条件注释对其他浏览器隐藏脚本时,必须使用 defer 属性 - 否则脚本将在其他浏览器中正常运行。)

参考:http : //www.impressivewebs.com/10-javascript-quick-tips-and-best-practices/

只是一个旁注:defer在 Firefox 3.5+ 中也支持
2021-05-09 23:44:58

如果可以推迟脚本,它们也可以移动到页面底部(正如@Christian 在评论中指出的那样)

就性能而言,这将是一个更好的选择,因为它不会阻止页面的其余部分加载。您可以将脚本放在</body>标签之前

主要浏览器对这个属性的支持很差,这本身应该是一个停止使用它的提示。

script 元素永远不应该存储在 body 元素中......除非你想尽最小的努力,而不是在下一个很酷的事情上工作,而是把所有的时间都花在维护糟糕的代码上。
2021-04-28 23:44:58