延迟属性 (Chrome) [英] Defer Attribute (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>
推荐答案
defer
和 async
是什么意思?
默认情况下,<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.
在所有 defer
和 async
脚本执行后,DOMContentLoaded
和 load
事件会触发.
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 月
defer
和async
被检入 Webkit.您应该很快就会在 Chrome 和 Safari 中看到它(它已经在 Chrome 开发者频道中,但它有点问题). - 我们仍在等待 Opera 实现
defer
和async
以及 IE 实现async
.
- 1997 IE 4 introduces
defer
. - 1998 HTML 4 spec mentions
defer
, but unfortunately it doesn't say exactly whendefer
scripts execute (All in order? Beforeonload
?). Thus, no other browsers implementdefer
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 beforeonload
. It also introducesasync
to specify scripts that can execute whenever they are downloaded without having to wait for each other. Unfortunately, HTML5 contradicts IE by not allowing inlinedefer
scripts. This breaks the invariant that alldefer
scripts are executed in order (if somedefer
scripts havesrc
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
andasync
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
andasync
and for IE to implementasync
.
目前没有单一的规则可以遵循.您必须为访问您网站的浏览器组选择最能平衡简单性、页面呈现延迟和脚本执行延迟的解决方案.
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 notasync
) 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 usedefer
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 theasync
. But Opera users get the worst of both worlds, because Opera begins execution immediately and doesn't understandasync
. 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.js 或 YUI 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屋!