我有几个关于<script>标签的async和defer属性的问题,据我的理解,它只在HTML5浏览器中工作。

我的一个站点有两个外部JavaScript文件,目前位于</body>标记上方;第一个是来自谷歌的jquery,第二个是一个本地外部脚本。

在网站加载速度方面

在我在页面底部的两个脚本中添加async是否有任何优势? 在这两个脚本中添加async选项并将它们放在<head>的页面顶部是否有任何优势? 这是否意味着他们会在页面加载时下载? 我认为这会导致HTML4浏览器的延迟,但是它会加速HTML5浏览器的页面加载吗?

使用<script defer src=…

在<head>中加载带有属性的两个脚本是否与在</body>之前加载脚本具有相同的影响? 同样,我认为这会降低HTML4浏览器的速度。

使用<script async src=…

如果我有两个脚本异步启用

他们会同时下载吗? 还是一页一页地看? 脚本的顺序会成为问题吗?例如,一个脚本依赖于另一个脚本,所以如果一个脚本下载得更快,第二个脚本可能无法正确执行等等。

最后,在HTML5得到更广泛的应用之前,我是否应该保持现状?


当前回答

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

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

Js:保存脚本相关文件。

Css:保存与样式相关的文件。

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

字体:保存字体相关文件


何时使用defer和async属性

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

当脚本用于DOM操作时,Defer属性非常有用。意味着脚本将应用于文档html。

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

当脚本不用于DOM操作时,Async属性非常有用。有时,您只需要脚本进行服务器端操作或处理缓存或cookie,而不需要用于DOM操作。意味着脚本与所使用的html无关。


使用defer和async时的有用链接: https://stackoverflow.com/a/68929270/7186739

其他回答

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

异步

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

<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>

发出并行请求来获取文件。 继续解析文档,就像它从未被打断过一样。 文件下载后立即执行各个脚本。

推迟

延迟与异步非常相似,但有一个主要区别。下面是浏览器遇到带有defer属性的脚本时会发生的情况。

<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>

进行并行请求以获取单个视频文件。 继续解析文档,就像它从未被打断过一样。 即使已经下载了脚本文件,也要完成文档解析。 按照文档中出现的顺序执行每个脚本。

参考:异步和延迟的区别

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

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

Js:保存脚本相关文件。

Css:保存与样式相关的文件。

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

字体:保存字体相关文件


何时使用defer和async属性

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

当脚本用于DOM操作时,Defer属性非常有用。意味着脚本将应用于文档html。

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

当脚本不用于DOM操作时,Async属性非常有用。有时,您只需要脚本进行服务器端操作或处理缓存或cookie,而不需要用于DOM操作。意味着脚本与所使用的html无关。


使用defer和async时的有用链接: https://stackoverflow.com/a/68929270/7186739

这张图片解释了正常的脚本标签,异步和延迟

异步脚本在加载脚本时立即执行,因此 不能保证执行的顺序(在 end可能在第一个脚本文件之前执行) 延迟脚本保证了它们出现的执行顺序 在页面中。

参考这个链接:http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html

保持你的脚本在</body>之前。Async可以在一些情况下与位于那里的脚本一起使用(参见下面的讨论)。延迟不会对位于那里的脚本产生太大影响,因为DOM解析工作基本上已经完成了。

这里有一篇文章解释了async和defer的区别:http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/。

如果你把脚本放在正文的末尾</body>之前,你的HTML在旧的浏览器中会显示得更快。所以,为了保持旧浏览器的加载速度,你不希望把它们放在其他地方。

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

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

当你真的不关心脚本何时加载,并且没有其他用户依赖于脚本加载时,Async更有用。最常被引用的使用async的例子是像谷歌analytics这样的分析脚本,你不希望等待任何东西,也不急于很快运行,它是独立的,所以没有其他东西依赖于它。

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

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

它是这样的:

Converting HTML bytes to characters depending on encoding we set to the document; Tokens are created according to characters. Tokens mean analyze characters and specify opening tangs and nested tags; From tokens separated nodes are created. they are objects and according to information delivered from tokenization process, engine creates objects which includes all necessary information about each node; after that DOM is created. DOM is tree data structure and represents whole hierarchy and information about relationship and specification of tags;

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

Browser只适用于对象模型,所以它需要知道所有关于DOM和CSSDOM的信息。

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

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

执行宏任务; 执行微任务; 呈现;

所以当你提供Javascript文件时,浏览器不知道JS代码要做什么,并停止所有的DOM构造过程,Javascript解释器开始解析和执行Javascript代码。

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

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

Async -意思是当代码被下载时执行,并且在下载过程中不阻塞DOM构造。

延迟——意思是在代码下载和浏览器完成DOM构造和渲染过程后执行。