加载并执行脚本的顺序 [英] load and execute order of scripts

查看:145
本文介绍了加载并执行脚本的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在html页面中包含JavaScript的方法有很多种。我知道以下选项:

There are so many different ways to include JavaScript in a html page. I know about the following options:


  • 内联代码或从外部URI加载

  • 包含在< ; head>或< body>标签[ 1 2 ]

  • 没有,推迟 async 属性(仅限外部脚本)

  • 包含在静态源中或由其他脚本动态添加(在不同的解析状态下,使用不同的方法)

  • inline code or loaded from external URI
  • included in <head> or <body> tag [1,2]
  • having none, defer or async attribute (only external scripts)
  • included in static source or added dynamically by other scripts (at different parse states, with different methods)

不计算browsercripts来自硬盘,javascript:URI和 onEvent -attributes [ 3 ],已经有16个替代方法可以让JS执行,我确定我忘记了什么。

Not counting browserscripts from the harddisk, javascript:URIs and onEvent-attributes [3], there are already 16 alternatives to get JS executed and I'm sure I forgot something.

我不是如此关注快速(并行)加载,我更加古玩我们关于执行顺序(可能取决于加载顺序和文档订单 )。 是否有良好的(跨浏览器)参考,涵盖了所有情况?例如。 http://www.websiteoptimization.com/speed/tweak/defer/ 仅限优惠其中有6个,并测试了大多数旧浏览器。

I'm not so concerned with fast (parallel) loading, I'm more curious about the execution order (which may depend on loading order and document order). Is there a good (cross-browser) reference that covers really all cases? E.g. http://www.websiteoptimization.com/speed/tweak/defer/ only deals with 6 of them, and tests mostly old browsers.

我担心没有,这是我的具体问题:我有一些(外部)头脚本用于初始化和脚本加载。然后我在身体的末尾有两个静态的内联脚本。第一个允许脚本加载器动态地将另一个脚本元素(引用外部js)附加到正文。第二个静态内联脚本想要使用添加的外部脚本中的js。是否可以依赖其他已执行的(以及为什么: - )?

As I fear there's not, here is my specific question: I've got some (external) head scripts for initialisation and script loading. Then I've got two static, inline scripts in the end of the body. The first one lets the script loader dynamically append another script element (referencing external js) to the body. The second of the static, inline scripts wants to use js from the added, external script. Can it rely on the other having been executed (and why :-)?

推荐答案

如果您没有动态加载脚本或将它们标记为延迟或异步,然后按照页面中遇到的顺序加载脚本。它是外部脚本还是内联脚本无关紧要 - 它们按照页面中遇到的顺序执行。外部脚本之后的内联脚本将保留,直到它们之前的所有外部脚本都已加载并运行。

If you aren't dynamically loading scripts or marking them as defer or async, then scripts are loaded in the order encountered in the page. It doesn't matter whether it's an external script or an inline script - they are executed in the order they are encountered in the page. Inline scripts that come after external scripts have are held until all external scripts that came before them have loaded and run.

异步脚本(无论它们如何指定为异步)加载并以不可预测的顺序运行。浏览器并行加载它们,并且可以按照它想要的顺序自由运行它们。

Async scripts (regardless of how they are specified as async) load and run in an unpredictable order. The browser loads them in parallel and it is free to run them in whatever order it wants.

多个异步事物之间没有可预测的顺序。如果需要一个可预测的订单,则必须通过从异步脚本注册加载通知并在加载适当的东西时手动排序javascript调用来编码。

There is no predictable order among multiple async things. If one needed a predictable order, then it would have to be coded in by registering for load notifications from the async scripts and manually sequencing javascript calls when the appropriate things are loaded.

动态插入脚本标记时,执行顺序的行为将取决于浏览器。您可以在此参考文章中查看Firefox的行为方式。简而言之,较新版本的Firefox默认动态添加脚本标记为异步,除非已设置脚本标记。

When a script tag is inserted dynamically, how the execution order behaves will depend upon the browser. You can see how Firefox behaves in this reference article. In a nutshell, the newer versions of Firefox default a dynamically added script tag to async unless the script tag has been set otherwise.

带有 async 的脚本标记可以在加载后立即运行。实际上,浏览器可能会将解析器从其正在执行的任何操作中暂停并运行该脚本。所以,它几乎可以随时运行。如果脚本被缓存,它可能几乎立即运行。如果脚本需要一段时间才能加载,它可能会在解析器完成后运行。使用 async 要记住的一件事是,它可以随时运行,并且该时间是不可预测的。

A script tag with async may be run as soon as it is loaded. In fact, the browser may pause the parser from whatever else it was doing and run that script. So, it really can run at almost any time. If the script was cached, it might run almost immediately. If the script takes awhile to load, it might run after the parser is done. The one thing to remember with async is that it can run anytime and that time is not predictable.

脚本标记为 defer 等待整个解析器完成,然后按照遇到的顺序运行标有 defer 的所有脚本。这允许您将几个依赖于彼此的脚本标记为 defer 。它们都将被推迟到文档解析器完成之后,但它们将按照它们遇到的顺序执行,保留它们的依赖关系。我认为 defer 就像脚本被放入一个队列中,该队列将在解析器完成后处理。从技术上讲,浏览器可能在任何时候在后台下载脚本,但是在解析器完成解析页面并解析和运行任何未标记为延迟或异步的内联脚本之后,它们才会执行或阻止解析器。

A script tag with defer waits until the entire parser is done and then runs all scripts marked with defer in the order they were encountered. This allows you to mark several scripts that depend upon one another as defer. They will all get postponed until after the document parser is done, but they will execute in the order they were encountered preserving their dependencies. I think of defer like the scripts are dropped into a queue that will be processed after the parser is done. Technically, the browser may be downloading the scripts in the background at any time, but they won't execute or block the parser until after the parser is done parsing the page and parsing and running any inline scripts that are not marked defer or async.

以下是该文章的引用:


脚本插入的脚本异步执行在IE和WebKit中,但在Opera和4.0之前的Firefox中同步

script-inserted scripts execute asynchronously in IE and WebKit, but synchronously in Opera and pre-4.0 Firefox.

HTML5规范的相关部分(对于较新的兼容浏览器,请此处。有很多关于异步行为的文章。显然,此规范不适用于您可能需要测试以确定的旧浏览器(或确认错误的浏览器)。

The relevant part of the HTML5 spec (for newer compliant browsers) is here. There is a lot written in there about async behavior. Obviously, this spec doesn't apply to older browsers (or mal-confirming browsers) who's behavior you would probably have to test to determine.

来自HTML5规范的引用:

A quote from the HTML5 spec:


然后,必须遵循以下第一个描述情况
的选项:

Then, the first of the following options that describes the situation must be followed:

如果元素具有src属性,并且元素具有延迟的
属性,并且该元素已被标记为解析器插入,则
元素没有异步属性

元素必须添加到
到脚本列表的末尾,当文档
完成解析与文档的关联时将执行
创建元素的解析器。

If the element has a src attribute, and the element has a defer attribute, and the element has been flagged as "parser-inserted", and the element does not have an async attribute The element must be added to the end of the list of scripts that will execute when the document has finished parsing associated with the Document of the parser that created the element.

网络任务源在获取算法完成后的
任务队列中放置的任务必须设置元素的准备好
是解析器执行的标志。解析器将处理执行脚本。

The task that the networking task source places on the task queue once the fetching algorithm has completed must set the element's "ready to be parser-executed" flag. The parser will handle executing the script.

如果元素具有src属性,并且元素已被标记为
为解析器插入 ,并且元素没有异步属性

元素是
文档的待处理解析阻塞脚本,它是创建元素的解析器。 (每个文档一次只能有一个这样的
脚本。)

If the element has a src attribute, and the element has been flagged as "parser-inserted", and the element does not have an async attribute The element is the pending parsing-blocking script of the Document of the parser that created the element. (There can only be one such script per Document at a time.)

网络任务源在任务队列上放置的任务一次
获取算法已完成必须设置元素的准备好
是解析器执行标志。解析器将处理执行脚本。

The task that the networking task source places on the task queue once the fetching algorithm has completed must set the element's "ready to be parser-executed" flag. The parser will handle executing the script.

如果元素没有src属性,并且元素已被
标记为解析器 - 插入,HTML解析器的文档或创建脚本元素的
XML解析器的样式表是
阻塞脚本
该元素是$ b的待处理解析阻塞脚本$ b创建元素的解析器的Document。 (每个文档一次只能有
一个这样的脚本。)

If the element does not have a src attribute, and the element has been flagged as "parser-inserted", and the Document of the HTML parser or XML parser that created the script element has a style sheet that is blocking scripts The element is the pending parsing-blocking script of the Document of the parser that created the element. (There can only be one such script per Document at a time.)

设置元素的准备解析器执行标志。解析器将
处理执行脚本。

Set the element's "ready to be parser-executed" flag. The parser will handle executing the script.

如果元素具有src属性,则没有async属性,
和没有设置force-async标志
该元素必须添加到
到脚本列表的末尾,这些脚本将尽快与
相关联地执行。准备脚本算法开始的
时间的脚本元素。

If the element has a src attribute, does not have an async attribute, and does not have the "force-async" flag set The element must be added to the end of the list of scripts that will execute in order as soon as possible associated with the Document of the script element at the time the prepare a script algorithm started.

网络任务源在任务队列上放置的任务一次
获取算法已完成必须运行以下步骤:

The task that the networking task source places on the task queue once the fetching algorithm has completed must run the following steps:

如果该元素现在不是将执行的脚本
列表中的第一个元素尽快订购它上面的
然后将元素标记为准备就绪,但在没有
执行脚本的情况下中止这些步骤。

If the element is not now the first element in the list of scripts that will execute in order as soon as possible to which it was added above, then mark the element as ready but abort these steps without executing the script yet.

执行:执行与第一个脚本
对应的脚本块这个脚本列表中的元素,只要
就可以按顺序执行。

Execution: Execute the script block corresponding to the first script element in this list of scripts that will execute in order as soon as possible.

从执行$ b $的脚本列表中删除第一个元素b按顺序排序。

Remove the first element from this list of scripts that will execute in order as soon as possible.

如果这个脚本列表将尽快按顺序执行$ ​​b $ b仍然不为空且第一个条目有已经标记为
就绪,然后跳回标记为执行的步骤。

If this list of scripts that will execute in order as soon as possible is still not empty and the first entry has already been marked as ready, then jump back to the step labeled execution.

如果元素具有src属性元素必须添加到
脚本集中,这些脚本将在准备脚本算法
开始时尽快执行脚本元素的Document

If the element has a src attribute The element must be added to the set of scripts that will execute as soon as possible of the Document of the script element at the time the prepare a script algorithm started.

网络任务源在获取算法完成后的任务队列中放置的任务必须执行脚本块并且
然后从脚本集中删除元素这将尽快以
执行。

The task that the networking task source places on the task queue once the fetching algorithm has completed must execute the script block and then remove the element from the set of scripts that will execute as soon as possible.

否则用户代理必须立即执行脚本块
,即使其他脚本已在执行。

Otherwise The user agent must immediately execute the script block, even if other scripts are already executing.

这篇关于加载并执行脚本的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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