684

我有几个关于属性async和标签的问题,据我了解defer,这些<script>标签仅适用于 HTML5 浏览器。

</body>我的一个网站有两个外部 JavaScript 文件,目前位于标签上方;第一个是来自 google 的

关于网站加载速度

  1. async添加到页面底部的两个脚本有什么好处吗?

  2. async将选项添加到两个脚本并将它们放在页面顶部是否有任何优势<head>

  3. 这是否意味着他们在页面加载时下载?

  4. 我认为这会导致 HTML4 浏览器延迟,但它会加快 HTML5 浏览器的页面加载速度吗?

使用<script defer src=...

  1. <head>使用属性加载两个脚本 与defer之前的脚本影响相同</body>吗?
  2. 我再次假设这会减慢 HTML4 浏览器的速度。

使用<script async src=...

如果我有两个async启用的脚本

  1. 他们会同时下载吗?
  2. 还是一次一个与页面的其余部分一起?
  3. 那么脚本的顺序会成为问题吗?例如,一个脚本依赖于另一个脚本,因此如果一个脚本下载速度更快,则第二个脚本可能无法正确执行,等等。

最后,在 HTML5 更常用之前,我最好保持原样吗?

4

13 回答 13

1119

这张图片解释了普通的脚本标签、异步和延迟

在此处输入图像描述

  • 加载脚本后立即执行异步脚本,因此它不能保证执行顺序(您最后包含的脚本可能在第一个脚本文件之前执行)

  • 延迟脚本保证它们出现在页面中的执行顺序。

参考此链接:http ://www.growthwiththeweb.com/2014/02/async-vs-defer-attributes.html

于 2016-09-26T19:37:39.113 回答
458

将您的脚本保留在</body>. 在少数情况下,异步可以与位于那里的脚本一起使用(参见下面的讨论)。Defer 不会对位于那里的脚本产生太大影响,因为 DOM 解析工作几乎已经完成。

这是一篇解释异步和延迟之间区别的文章:http: //peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/

如果您将脚本保留在正文末尾之前,您的 HTML 将在旧浏览器中显示得更快</body>。因此,为了保持旧浏览器的加载速度,您不想将它们放在其他任何地方。

如果您的第二个脚本依赖于第一个脚本(例如,您的第二个脚本使用第一个脚本中加载的 jQuery),那么您不能在没有额外代码来控制执行顺序的情况下使它们异步,但您可以使它们延迟,因为延迟脚本会仍然按顺序执行,只是在文档被解析之后才执行。如果您有该代码并且不需要立即运行脚本,则可以使它们异步或延迟。

您可以将脚本放在<head>标签中并将它们设置为defer,脚本的加载将被延迟,直到 DOM 被解析,这将在支持延迟的新浏览器中快速显示页面,但这对您没有任何帮助在较旧的浏览器中,它实际上并不比将脚本</body>放在所有浏览器中都快。所以,你可以明白为什么最好把它们放在前面</body>

当您真的不关心脚本何时加载并且没有其他用户依赖于该脚本加载时,异步会更有用。使用异步最常被引用的示例是像 Google Analytics 这样的分析脚本,您不想等待任何东西,并且很快运行并不急迫,它是独立的,所以没有其他东西依赖它。

通常 jQuery 库不适合异步,因为其他脚本依赖于它,并且您希望安装事件处理程序以便您的页面可以开始响应用户事件,并且您可能需要运行一些基于 jQuery 的初始化代码来建立初始状态的页面。它可以异步使用,但其他脚本必须在加载 jQuery 之前进行编码才能执行。

于 2012-05-29T23:45:32.923 回答
245

HTML5: async,defer

在 HTML5 中,您可以告诉浏览器何时运行您的 JavaScript 代码。有3种可能:

<script       src="myscript.js"></script>

<script async src="myscript.js"></script>

<script defer src="myscript.js"></script>
  1. 如果没有asyncor defer,浏览器将立即运行您的脚本,然后再渲染您的脚本标签下方的元素。

  2. 使用async(异步),浏览器将继续加载 HTML 页面并呈现它,同时浏览器加载和执行脚本。

  3. 使用defer,浏览器将在页面完成解析时运行您的脚本。(不需要完成所有图像文件的下载。这很好。)

于 2013-10-24T03:47:55.660 回答
43

async和脚本都defer立即开始下载而无需暂停解析器,并且都支持可选的onload处理程序来解决执行依赖于脚本的初始化的常见需求。

执行脚本的时间async和中心之间的区别。defer每个async脚本在完成下载后和窗口的加载事件之前第一次执行。这意味着有可能(并且很可能)async脚本没有按照它们在页面中出现的顺序执行。而另一方面,defer脚本保证按照它们在页面中出现的顺序执行。该执行在解析完全完成后开始,但在文档DOMContentLoaded事件之前。

来源和更多细节:这里

于 2014-06-12T11:30:43.807 回答
40

面临同样的问题,现在清楚地了解两者将如何工作。希望这个参考链接会有所帮助......

异步

当您将 async 属性添加到脚本标记时,将发生以下情况。

<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>
  1. 发出并行请求以获取文件。
  2. 继续解析文档,就好像它从未被中断过一样。
  3. 下载文件时执行各个脚本。

推迟

Defer 与 async 非常相似,但有一个主要区别。当浏览器遇到具有 defer 属性的脚本时,会发生以下情况。

<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
  1. 发出并行请求以获取单个文件。
  2. 继续解析文档,就好像它从未被中断过一样。
  3. 即使脚本文件已下载,也完成对文档的解析。
  4. 按照在文档中遇到的顺序执行每个脚本。

参考:异步和延迟之间的区别

于 2016-10-12T07:16:14.280 回答
26

async并将defer在 HTML 解析期间下载文件。两者都不会中断解析器。

  • 具有属性的脚本async将在下载后执行。而具有属性的脚本defer将在完成 DOM 解析后执行。

  • 加载的脚本async不保证任何顺序。使用属性加载的脚本defer保持它们在 DOM 上出现的顺序。

<script async>当脚本不依赖任何东西时使用。当脚本依赖使用时<script defer>

最好的解决方案是<script>在身体的底部添加。阻塞或渲染不会有问题。

于 2015-02-23T01:25:29.017 回答
7

好的做法是将所有文件保留在源文件夹中以快速加载源文件。您需要下载所有与脚本、样式、图标和图像相关的文件,并将这些文件放入您的项目文件夹中。

在您的项目中创建这些文件夹以保存不同的源文件,然后将所需文件从这些文件夹添加到页面中。

js:保存脚本相关文件。

css:保存样式相关文件。

img:保存图像/图标相关文件

fonts:保存字体相关文件


何时使用 defer 和 async 属性

defer 属性:首先它会下载脚本文件,然后等待 html 解析。html解析结束后,将执行脚本。换句话说,它将保证所有脚本在 html 解析后执行。

当脚本用于 DOM 操作时,延迟属性很有用。意味着脚本将应用于文档 html。

async 属性:它将下载脚本文件并执行,无需等待 html 解析结束。换句话说,它不能保证所有的脚本都会在 html 解析之后执行。

当脚本不用于 DOM 操作时,异步属性很有用。有时您只需要脚本用于服务器端操作或处理缓存或 cookie,而不需要用于 DOM 操作。表示脚本与使用的 html 无关。

在此处输入图像描述


何时使用延迟和异步的有用链接: https ://stackoverflow.com/a/68929270/7186739

于 2021-08-27T18:37:06.147 回答
5
于 2019-08-13T21:41:25.360 回答
1

似乎 defer 和 async 的行为取决于浏览器,至少在执行阶段是这样。注意, defer 仅适用于外部脚本。我假设 async 遵循相同的模式。

在 IE 11 及更低版本中,顺序似乎是这样的:

  • 异步(在页面加载时可以部分执行)
  • 无(可以在页面加载时执行)
  • defer(在页面加载后执行,所有延迟按文件中的放置顺序)

在 Edge、Webkit 等中,async 属性似乎被忽略或放在最后:

  • data-pagespeed-no-defer(在任何其他脚本之前执行,同时页面正在加载)
  • 无(可以在页面加载时执行)
  • defer (等到 DOM 加载完毕,全部按文件中的放置顺序延迟)
  • 异步(似乎要等到 DOM 加载)

在较新的浏览器中, data-pagespeed-no-defer 属性在任何其他外部脚本之前运行。这适用于不依赖于 DOM 的脚本。

注意:当您需要明确的外部脚本执行顺序时,请使用 defer。这告诉浏览器按文件中的放置顺序执行所有延迟脚本。

旁白:加载时外部 javascript 的大小确实很重要……但对执行顺序没有影响。

如果您担心脚本的性能,您可能需要考虑缩小或简单地使用 XMLHttpRequest 动态加载它们。

于 2017-07-28T02:01:05.470 回答
0

渲染引擎经过几个步骤,直到它在屏幕上绘制任何内容。

它看起来像这样:

  1. 根据我们为文档设置的编码将 HTML 字节转换为字符;
  2. 令牌是根据字符创建的。标记意味着分析字符并指定开头的唐和嵌套的标签;
  3. 从令牌中创建分离的节点。它们是对象,根据从标记化过程传递的信息,引擎创建对象,其中包括有关每个节点的所有必要信息;
  4. 在创建 DOM 之后。DOM 是树形数据结构,表示整个层次结构以及关于标签关系和规范的信息;

同样的过程也适用于 CSS。CSS渲染引擎为CSS创建不同/分离的数据结构,但它被称为CSSOM(CSS对象模型)

浏览器仅适用于对象模型,因此它需要了解有关 DOM 和 CSSDOM 的所有信息。

下一步是以某种方式结合 DOM 和 CSSOM。因为没有 CSSOM 的浏览器不知道如何在渲染过程中设置每个元素的样式。

以上所有信息意味着,您在 html(javascript、css)浏览器中提供的任何内容都将暂停 DOM 构建过程。如果您熟悉事件循环,那么事件循环如何执行任务有一个简单的规则:

  1. 执行宏任务;
  2. 执行微任务;
  3. 渲染;

因此,当您提供 Javascript 文件时,浏览器不知道 JS 代码将要做什么并停止所有 DOM 构建过程,并且 Javascript 解释器开始解析和执行 Javascript 代码。

即使您在 body 标记的末尾提供了 Javascript,浏览器也会对 HTML 和 CSS 执行上述所有步骤,但渲染除外。它会找出 Script 标签并停止,直到 JS 完成。

但是 HTML 为 script 标签提供了两个额外的选项:async 和 defer。

异步 - 表示下载时执行代码,并且在下载过程中不阻塞 DOM 构建。

Defer - 表示在代码下载完成并且浏览器完成 DOM 构建和渲染过程后执行代码。

于 2021-01-05T13:28:39.197 回答
0

你可以从这里找到不同之处

在此处输入图像描述

在此处输入图像描述

于 2022-03-04T09:37:52.190 回答
-1

如果您的脚本不包含 DOM 操作并且其他脚本不依赖于此,则异步是合适的。例如:引导 cdn、jquery

如果您的脚本包含 DOM 操作并且其他脚本依赖于此,则延迟适用。

例如: <script src=”createfirst.js”&gt; //let this will create element <script src=”showfirst.js”&gt; //after createfirst create element it will show that.

因此使它:例如: <script defer src=”createfirst.js”&gt; //let this will create element <script defer src=”showfirst.js”&gt; //after createfirst create element it will

这将按顺序执行脚本。

但如果我做了:例如: <script async src=”createfirst.js”&gt; //let this will create element <script defer src=”showfirst.js”&gt; //after createfirst create element it will

然后,此代码可能会导致意外结果。Coz:如果 html 解析器访问 createfirst 脚本。它不会停止 DOM 创建并开始从 src 下载代码。一旦 src 被解析/代码被下载,它将立即与 DOM 并行执行。

如果 showfirst.js 比 createfirst.js 先执行怎么办。如果 createfirst 需要很长时间(假设在 DOM 解析完成后),这可能是可能的。然后,showfirst 将立即执行。

于 2021-01-28T11:24:54.757 回答
-2

正常 vs 异步 vs 延迟

简而言之,Normal vs Async vs Defer

如果你没有在脚本标签上指定任何东西,它的正常流程和那些数字 1,2,3,4 代表它如何执行的步骤

于 2021-07-27T06:07:37.643 回答