延迟属性 (Chrome) [英] Defer Attribute (Chrome)

查看:30
本文介绍了延迟属性 (Chrome)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Chrome 对我来说一直是网络标准的参考,不幸的是 defer 不受支持,IE 从 5.5 版开始支持它.为什么?

Chrome for me has always been a reference on web standards, unfortunately the defer isn't supported and IE supports it since version 5.5. Why ?

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>

推荐答案

deferasync 是什么意思?

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

What do defer and async mean?

By default, a <script src=...></script> tag is evil! The browser must halt parsing the HTML until the script is downloaded and executed (since the script might call document.write(...) or define global variables that later scripts depend on). This means that any images and stylesheets that are after the script tag don't start downloading until after the script has finished downloading and executing. External scripts typically make the Web load much more slowly, which is why NoScript has become so popular.

微软引入了defer来解决这个问题.如果你使用 <script defer src=...></script>,你保证不调用 document.write(...).defer 外部脚本将立即开始下载,但在页面呈现后才会执行.页面呈现后,所有 defer 脚本都按照它们声明的顺序执行.并非所有浏览器都实现了 defer.

Microsoft introduced defer to solve the problem. If you use <script defer src=...></script>, you promise not to call document.write(...). A defer external script will start downloading immediately but won't execute until after the page is rendered. After the page has rendered, all defer scripts are executed in the same order that they were declared. Not all browsers implement defer yet.

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

HTML5 introduced the async attribute which may execute any time--possibly before the page has finished parsing or even before other defer/async scripts that are still downloading. But it's harder to use multiple async scripts because their execution order is not guaranteed. Like defer, not all browsers implement async yet.

在所有 deferasync 脚本执行后,DOMContentLoadedload 事件会触发.

After all defer and async scripts have executed, the DOMContentLoaded and load events fire.

  • 1997 IE 4 引入了 defer.
  • 1998 HTML 4 规范提及 defer,但不幸的是它没有准确说明 defer 脚本何时执行(全部按顺序执行?在 onload 之前?).因此,没有其他浏览器实现 defer 因为没有人想对 IE 的行为进行逆向工程或破坏可能取决于 IE 特性的脚本.(例如,请参见 Mozilla 功能请求).
  • 2006 HTML5 草案最终描述了实现 defer 所需的细节:defer 脚本应该在页面的其余部分被解析之后,并且在 加载.它还引入了 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 年 9 月 deferasync 被检入 Webkit.您应该很快就会在 Chrome 和 Safari 中看到它(它已经在 Chrome 开发者频道中,但它有点问题).
  • 我们仍在等待 Opera 实现 deferasync 以及 IE 实现 async.
  • 1997 IE 4 introduces defer.
  • 1998 HTML 4 spec mentions defer, but unfortunately it doesn't say exactly when defer scripts execute (All in order? Before onload?). Thus, no other browsers implement defer because no one wants to reverse-engineer IE's behavior or break scripts that might depend on IE's peculiarities. (See the Mozilla feature request, for example).
  • 2006 HTML5 draft finally describes the details needed to implement defer: defer scripts should all be executed in order after the rest of the page is parsed, and before onload. It also introduces async to specify scripts that can execute whenever they are downloaded without having to wait for each other. Unfortunately, HTML5 contradicts IE by not allowing inline defer scripts. This breaks the invariant that all defer scripts are executed in order (if some defer scripts have src and some have inline content).
  • 2009 Gecko 1.9.1 (Firefox 3.5) supports defer.
  • 2010-01 Gecko 1.9.2 (Firefox 3.6) supports async.
  • 2010-09 defer and async are checked into Webkit. You should see it in Chrome and Safari very soon (it's already in the Chrome dev channel but it's a bit buggy).
  • We're still waiting for Opera to implement defer and async and for IE to implement async.

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

There's no single rule to follow at this time. You have to choose the solution that best balances simplicity, page render latency, and script execution latency for the set of browsers that access your website.

  • 正如其他人指出的那样,在脚本执行之前呈现页面的最简单方法是将您的脚本放在页面底部.但如果脚本是必不可少的,或者网页包含大量 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 推荐的模式,适用于许多网页.
  • The simplest way to have the page render before the scripts execute, as others have pointed out, is to put your scripts at the bottom of the page. But if the scripts are essential, or the webpage contains lots of HTML, then you should put your scripts higher up on the page.
  • If your script is standalone and your customers use IE or new versions of Firefox, use <script async defer src=...></script>: This allows rendering to continue in parallel to script downloading for IE and the newest HTML5 browsers but causes pre-HTML5 browsers (including all versions of Opera) to block.
  • If one external script depends on another, mark them both defer (but not async) and they will be executed in the order that they were declared (except IE<=9 in certain conditions can execute them out of order). Again, this allows rendering to continue in parallel to script downloading in IE and HTML5-aware Gecko/Webkit, but older browsers and Opera will suffer. It's a good idea to use defer even if the scripts are at the bottom of the page so that they download in parallel with each other.
  • Never use defer for inline scripts because the HTML5 draft has taken away the execution order guarantee.
  • If your audience includes many Opera or old Firefox/Safari users, the following snippet will execute the script after parsing the document on most pre-HTML5 browsers (IE, Webkit, need to test old Firefox), while the newest HTML5-aware browsers start downloading immediately but won't block to execute the script because of the async attribute. In other words, most older browsers treat it like a script at the bottom of the page, and newest browsers recognize the async. But Opera users get the worst of both worlds, because Opera begins execution immediately and doesn't understand async. This is the pattern recommended by Google Analytics for the urchin on many webpages.

片段:

<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 的副本 而不是您自己的,以增加浏览器已经缓存它的可能性.
    • If another script depends on the first script to load, then you can use the same pattern as above, but listen to the onload event of the first script element before executing the second script. See the LABjs example for how to wait for another script to load.
    • If you have multiple scripts with complicated dependencies, use LAB.js or the YUI Loader to make them download in parallel and execute in some valid order.
    • If you're using a popular library such as jQuery, consider using Google's copy rather than your own to increase the likelihood that the browser has already cached it.
    • 更新:如果您将脚本拆分为模块并希望提高性能,我建议您使用耦合异步脚本";Steve Souder 的更快的网站 一章.它包含的提示/技巧不仅可以控制执行顺序,还可以延迟脚本解析以提高性能.

      Update: If you have scripts split into modules and want to improve performance, I recommend the "Coupling Asynchronous Scripts" chapter of Even Faster Web Sites by Steve Souder. It contains tips/tricks for not only controlling execution order but also to delay parsing of scripts to improve performance.

      这篇关于延迟属性 (Chrome)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆