From 7baed96a35a90889742944dd3569c8b43ae2c2a4 Mon Sep 17 00:00:00 2001 From: LycheeEng Date: Sun, 9 Jun 2019 17:46:34 +0800 Subject: [PATCH 01/27] Translate 2-ui/3-event-details/12-script-async-defer/article.md --- .../12-script-async-defer/article.md | 192 ++++++++++++++++++ .../12-script-async-defer/long.js | 32 +++ .../12-script-async-defer/small.js | 3 + 3 files changed, 227 insertions(+) create mode 100755 2-ui/3-event-details/12-script-async-defer/article.md create mode 100755 2-ui/3-event-details/12-script-async-defer/long.js create mode 100755 2-ui/3-event-details/12-script-async-defer/small.js diff --git a/2-ui/3-event-details/12-script-async-defer/article.md b/2-ui/3-event-details/12-script-async-defer/article.md new file mode 100755 index 0000000000..4c6829e8c7 --- /dev/null +++ b/2-ui/3-event-details/12-script-async-defer/article.md @@ -0,0 +1,192 @@ +# Script 标签属性:async, defer + +现代脚本中,脚本往往比 HTML 更 “重”:它们的大小通常更大,处理时间也更长。 + +当浏览器加载 HTML 时遇到 `` 标签,浏览器就不能继续构建 DOM。它必须立刻执行此脚本。对于外部脚本也是一样的 ``:浏览器必须等脚本下载,执行结束后才能处理剩余的页面。 + +这会导致两个重要的问题: + +1. 脚本不能访问到位于它们下面的 DOM 元素,因此,脚本不能给它们添加事件等。 +2. 如果页面顶部有一个庞大的脚本,它会 “阻塞页面”。在脚本下载并执行结束前,用户都不能看到页面内容: + +```html run height=100 +

...content before script...

+ + + + +

...content after script...

+``` + +这里有一些解决办法。例如,我们可以把脚本放在页面底部。此时,它可以访问到它上面的元素,并且不会阻塞页面显示内容: + +```html + + ...all content is above the script... + + + +``` + +但是这样的方案绝非完美。例如:浏览器只有在下载完整的 HTML 文档后才会注意到脚本(并且开始下载它)。对于长的 HTML 文档来说,这样的延迟必须引起注意。 + +对于网络连接很快的人来说,这不值一提。但是这个世界上仍然有很多地区的人们他们使用很慢的网络连接,并且使用远非完美的移动互联网。 + +幸运的是,这里有两个 ` + + +

...content after script...

+``` + +- 具有 `defer` 属性的脚本不会阻塞页面的加载。 +- 具有 `defer` 属性的脚本总是要等到 DOM 解析完毕,且在 `DOMContentLoaded` 事件之前执行。 + +下面的例子演示了这一过程: + +```html run height=100 +

...content before scripts...

+ + + + + +

...content after scripts...

+``` + +1. 页面内容立即显示。 +2. `DOMContentLoaded` 等待 defer 脚本下载执行结束。它仅在脚本 `(2)` 下载且执行结束后才被触发。 + +Defer 脚本保持他们的相对顺序,就像常规脚本一样。 + +所以,如果我们有一个长脚本在前,一个短脚本在后,那么后者就会等待前者。 + +```html + + +``` + +```smart header="短脚本先下载完成,但是后执行" +浏览器解析页面找到 script 属性并并行下载它们,以提高性能。因此,在上面的实例中,两个脚本并行下载。`small.js` 可能会先下载完成。 + +但是规范要求脚本按照文档顺序执行,因此它要等到 `long.js` 执行结束。 +``` + +```smart header="`defer` 属性仅适用于外部脚本" +`defer` 属性会忽略没有 `src` 属性的 ` + + + + +

...content after scripts...

+``` + +1. 页面内容立刻显示出来:`async` 脚本不会阻塞页面加载。 +2. `DOMContentLoaded` 可以在 `async` 之前或之后触发,不能保证谁在前谁在后。 +3. Async 脚本不会等待彼此。一个小的脚本 `small.js` 放在后面,但是可能会比 `long.js` 这个长脚本先加载完成,所以尽管 `small.js` 在后面,但是它可能先运行。这一行为被称为 “加载优先” 顺序。 + +当我们将独立的第三方脚本集成到页面的时候,此时采用异步加载方式是非常棒的:计数器,广告等等,因为它们不依赖于我们的脚本,同样我们的脚本也不应该等待它们加载完成: + +```html + + +``` + +## 动态脚本(Dynamic scripts) + +我们也可以使用 JavaScript 动态地添加脚本: + +```js run +let script = document.createElement('script'); +script.src = "/article/script-async-defer/long.js"; +document.body.append(script); // (*) +``` + +当脚本附加到文档 `(*)` 时,脚本就会开始加载: + +**默认情况下,动态脚本表现为“异步”行为** + +这也就是说: +- 它们不会等待其他内容,其他的内容也不会等待它们。 +- 先加载完成的脚本先运行(“load-first” order) + +我们可以通过将 `async` 属性显示修改为 `false` 来将加载优先顺序修改为文档顺序(就像常规脚本一样): + +```js run +let script = document.createElement('script'); +script.src = "/article/script-async-defer/long.js"; + +*!* +script.async = false; +*/!* + +document.body.append(script); +``` + +例如,这里我们添加了两个脚本。在没有设置 `script.async=false` 时,它们执行顺序为加载优先顺序(即 `small.js` 可能先运行)。但是当设置了 `script.async=false` 后,脚本执行顺序就是它在文档中的顺序: + +```js run +function loadScript(src) { + let script = document.createElement('script'); + script.src = src; + script.async = false; + document.body.append(script); +} + +// 由于 async=false 属性存在,long.js 会先运行 +loadScript("/article/script-async-defer/long.js"); +loadScript("/article/script-async-defer/small.js"); +``` + +## 总结 + +`async` 和 `defer` 属性有一个共同点:它们都不会阻塞页面的渲染。因此,用户可以阅读页面内容并立即熟悉该页面。 + +但是它们之间也存在一些本质的区别: + +| 类型 | 顺序 | `DOMContentLoaded` | +|---------|---------|---------| +| `async` | *加载优先顺序*。脚本在文档中的顺序不重要——先加载完成先运行 | 无关紧要。可能在文档还未完全下载时加载执行。如果脚本很小或者来自于缓存,同时文档又足够长,就会发生这种情况。| +| `defer` | *文档顺序*(它们在文档中的位置) | 在 `DOMContentLoaded` 之前且在文档加载解析之后执行(可能需要等待)。| + +```warn header="没有脚本的页面应该也是可用的" +请注意,如果你使用的是 `defer`,那么在脚本加载之前页面都是“可见”的。 + +因此,用户可以阅读这个页面内容,但是一些图形组件可能没有准备完成。 + +所以,这就需要在页面适当位置添加 “加载” 进度指示,禁用无效的按钮,以清楚地向用户显示什么准备好了什么没有准备好。 +``` + +在开发中,通常在脚本需要整个 DOM 和/或它们相对执行顺序很重要的时候,此时使用 `defer` 属性。而当脚本之间互相独立,比如计数器或者广告,并且它们相对执行顺序不重要的时候,此时使用 `async` 属性。 \ No newline at end of file diff --git a/2-ui/3-event-details/12-script-async-defer/long.js b/2-ui/3-event-details/12-script-async-defer/long.js new file mode 100755 index 0000000000..48710f1c62 --- /dev/null +++ b/2-ui/3-event-details/12-script-async-defer/long.js @@ -0,0 +1,32 @@ +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... +// ...long js... ...long js... ...long js... ...long js... ...long js... ...long js... + +alert("Long script loaded"); diff --git a/2-ui/3-event-details/12-script-async-defer/small.js b/2-ui/3-event-details/12-script-async-defer/small.js new file mode 100755 index 0000000000..ec743a025d --- /dev/null +++ b/2-ui/3-event-details/12-script-async-defer/small.js @@ -0,0 +1,3 @@ +// ...small js... + +alert("Small script loaded"); From a8012590df4f47c62169665ad2bb3b3622a209fd Mon Sep 17 00:00:00 2001 From: LycheeEng Date: Mon, 10 Jun 2019 08:59:43 +0800 Subject: [PATCH 02/27] Sync English version file location --- .../03-script-async-defer}/article.md | 0 .../03-script-async-defer}/long.js | 0 .../03-script-async-defer}/small.js | 0 2-ui/5-loading/index.md | 1 + 4 files changed, 1 insertion(+) rename 2-ui/{3-event-details/12-script-async-defer => 5-loading/03-script-async-defer}/article.md (100%) rename 2-ui/{3-event-details/12-script-async-defer => 5-loading/03-script-async-defer}/long.js (100%) rename 2-ui/{3-event-details/12-script-async-defer => 5-loading/03-script-async-defer}/small.js (100%) create mode 100755 2-ui/5-loading/index.md diff --git a/2-ui/3-event-details/12-script-async-defer/article.md b/2-ui/5-loading/03-script-async-defer/article.md similarity index 100% rename from 2-ui/3-event-details/12-script-async-defer/article.md rename to 2-ui/5-loading/03-script-async-defer/article.md diff --git a/2-ui/3-event-details/12-script-async-defer/long.js b/2-ui/5-loading/03-script-async-defer/long.js similarity index 100% rename from 2-ui/3-event-details/12-script-async-defer/long.js rename to 2-ui/5-loading/03-script-async-defer/long.js diff --git a/2-ui/3-event-details/12-script-async-defer/small.js b/2-ui/5-loading/03-script-async-defer/small.js similarity index 100% rename from 2-ui/3-event-details/12-script-async-defer/small.js rename to 2-ui/5-loading/03-script-async-defer/small.js diff --git a/2-ui/5-loading/index.md b/2-ui/5-loading/index.md new file mode 100755 index 0000000000..9a9665e08a --- /dev/null +++ b/2-ui/5-loading/index.md @@ -0,0 +1 @@ +# 加载文档和其他资源 \ No newline at end of file From bb032fc6e39a224c916221e9c0b757f004fe62bd Mon Sep 17 00:00:00 2001 From: LycheeEng Date: Mon, 10 Jun 2019 09:47:43 +0800 Subject: [PATCH 03/27] Fix folder name --- .../{03-script-async-defer => 02-script-async-defer}/article.md | 0 .../{03-script-async-defer => 02-script-async-defer}/long.js | 0 .../{03-script-async-defer => 02-script-async-defer}/small.js | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename 2-ui/5-loading/{03-script-async-defer => 02-script-async-defer}/article.md (100%) rename 2-ui/5-loading/{03-script-async-defer => 02-script-async-defer}/long.js (100%) rename 2-ui/5-loading/{03-script-async-defer => 02-script-async-defer}/small.js (100%) diff --git a/2-ui/5-loading/03-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md similarity index 100% rename from 2-ui/5-loading/03-script-async-defer/article.md rename to 2-ui/5-loading/02-script-async-defer/article.md diff --git a/2-ui/5-loading/03-script-async-defer/long.js b/2-ui/5-loading/02-script-async-defer/long.js similarity index 100% rename from 2-ui/5-loading/03-script-async-defer/long.js rename to 2-ui/5-loading/02-script-async-defer/long.js diff --git a/2-ui/5-loading/03-script-async-defer/small.js b/2-ui/5-loading/02-script-async-defer/small.js similarity index 100% rename from 2-ui/5-loading/03-script-async-defer/small.js rename to 2-ui/5-loading/02-script-async-defer/small.js From 53f9f19d136050e478d21940f9006dc6873eab56 Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 09:37:50 +0800 Subject: [PATCH 04/27] Update 2-ui/5-loading/02-script-async-defer/article.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 徐玥 --- 2-ui/5-loading/02-script-async-defer/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index 4c6829e8c7..649163d71e 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -81,7 +81,7 @@ Defer 脚本保持他们的相对顺序,就像常规脚本一样。 ```smart header="短脚本先下载完成,但是后执行" 浏览器解析页面找到 script 属性并并行下载它们,以提高性能。因此,在上面的实例中,两个脚本并行下载。`small.js` 可能会先下载完成。 -但是规范要求脚本按照文档顺序执行,因此它要等到 `long.js` 执行结束。 +但是规范要求脚本按照文档顺序执行,因此它要等到 `long.js` 执行结束才会被执行。 ``` ```smart header="`defer` 属性仅适用于外部脚本" @@ -189,4 +189,4 @@ loadScript("/article/script-async-defer/small.js"); 所以,这就需要在页面适当位置添加 “加载” 进度指示,禁用无效的按钮,以清楚地向用户显示什么准备好了什么没有准备好。 ``` -在开发中,通常在脚本需要整个 DOM 和/或它们相对执行顺序很重要的时候,此时使用 `defer` 属性。而当脚本之间互相独立,比如计数器或者广告,并且它们相对执行顺序不重要的时候,此时使用 `async` 属性。 \ No newline at end of file +在开发中,通常在脚本需要整个 DOM 和/或它们相对执行顺序很重要的时候,此时使用 `defer` 属性。而当脚本之间互相独立,比如计数器或者广告,并且它们相对执行顺序不重要的时候,此时使用 `async` 属性。 From 48e50efbb7db941aff43d346414e7487e3d92875 Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 09:38:08 +0800 Subject: [PATCH 05/27] Update 2-ui/5-loading/02-script-async-defer/article.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 徐玥 --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index 649163d71e..fb591f2d5e 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -95,7 +95,7 @@ Defer 脚本保持他们的相对顺序,就像常规脚本一样。 - 页面不会等待异步脚本,它会继续处理页面并显示内容。 - `DOMContentLoaded` 和 async 脚本不会彼此等待: - `DOMContentLoaded` 可能发生在异步脚本之前(此时异步脚本在页面加载完成后才加载完成) - - `DOMContentLoaded` 发生在异步脚本之后(此时异步脚本可能很短或者是从 HTTP 缓存中加载的) + - `DOMContentLoaded` 也可能发生在异步脚本之后(此时异步脚本可能很短或者是从 HTTP 缓存中加载的) - 其他脚本不会等待 `async` 脚本加载完成,同样 `async` 脚本也不会等待其他脚本。 因此,如果我们有几个 `async` 脚本,它们可能按任意次序执行,总之是先加载完成的就先运行: From c5b6715d7d387c86788bb6dfcbf416b5d6e5eafb Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 09:57:03 +0800 Subject: [PATCH 06/27] Update 2-ui/5-loading/02-script-async-defer/article.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 徐玥 --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index fb591f2d5e..105c1a3112 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -172,7 +172,7 @@ loadScript("/article/script-async-defer/small.js"); ## 总结 -`async` 和 `defer` 属性有一个共同点:它们都不会阻塞页面的渲染。因此,用户可以阅读页面内容并立即熟悉该页面。 +`async` 和 `defer` 属性有一个共同点:它们都不会阻塞页面的渲染。因此,用户可以立即阅读并了解页面内容。 但是它们之间也存在一些本质的区别: From 01f91aea1eee4548a7a1337e13be720505509e9d Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 09:58:38 +0800 Subject: [PATCH 07/27] Update 1-js/13-modules/03-modules-dynamic-imports/article.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 徐玥 --- 1-js/13-modules/03-modules-dynamic-imports/article.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-js/13-modules/03-modules-dynamic-imports/article.md b/1-js/13-modules/03-modules-dynamic-imports/article.md index ac8ccf452a..33b600adfc 100755 --- a/1-js/13-modules/03-modules-dynamic-imports/article.md +++ b/1-js/13-modules/03-modules-dynamic-imports/article.md @@ -1,6 +1,6 @@ # 动态导入(Dynamic imports) -我们在前面章节中介绍的导出和导入语句成为“静态”导入。 +在前面章节中介绍的 export 和 import 语句我们可以称之为“静态”的导入和导出。 这是因为它们确实是静态的,语法非常严格。 @@ -49,4 +49,4 @@ import(modulePath) 所以,动态导入用起来很简单。 -此外,动态导入可以像常规脚本一样工作,不需要额外指出 `script type="module"`。 \ No newline at end of file +此外,动态导入可以像常规脚本一样工作,不需要额外指出 `script type="module"`。 From ba698cce30eedfa16ca6dba8eb046702d7158f87 Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 09:59:10 +0800 Subject: [PATCH 08/27] Update 1-js/13-modules/03-modules-dynamic-imports/article.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 徐玥 --- 1-js/13-modules/03-modules-dynamic-imports/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/13-modules/03-modules-dynamic-imports/article.md b/1-js/13-modules/03-modules-dynamic-imports/article.md index 33b600adfc..e2d77b8388 100755 --- a/1-js/13-modules/03-modules-dynamic-imports/article.md +++ b/1-js/13-modules/03-modules-dynamic-imports/article.md @@ -24,7 +24,7 @@ if(...) { } ``` -这是因为,导入/导出的目的是为了代码提供主干结构。这是非常好的事情,因为这样可以分析代码结构,可以收集和打包模块,可以删除未使用的导出(tree-shaken)。这些都是可能的,因为一切都是固定的。 +这是因为,导入/导出的目的是为了给代码提供主干结构。这是非常好的事情,因为这样可以分析代码结构,可以收集和打包模块,可以删除未使用的导出(tree-shaken)。这些都是可以实现的,因为一切都是固定的。 但是,我们如何才能动态的按需导入模块呢? From fe2c2fabaee5808d62124079c4fa7ec69ca45270 Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 10:12:40 +0800 Subject: [PATCH 09/27] Update 2-ui/5-loading/02-script-async-defer/article.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 徐玥 --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index 105c1a3112..acde3f6426 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -178,7 +178,7 @@ loadScript("/article/script-async-defer/small.js"); | 类型 | 顺序 | `DOMContentLoaded` | |---------|---------|---------| -| `async` | *加载优先顺序*。脚本在文档中的顺序不重要——先加载完成先运行 | 无关紧要。可能在文档还未完全下载时加载执行。如果脚本很小或者来自于缓存,同时文档又足够长,就会发生这种情况。| +| `async` | *加载优先顺序*。脚本在文档中的顺序不重要 —— 先加载完成先运行 | 无关紧要。可能在文档还未完全下载前加载执行。如果脚本很小或者来自于缓存,同时文档又足够长,就会发生这种情况。| | `defer` | *文档顺序*(它们在文档中的位置) | 在 `DOMContentLoaded` 之前且在文档加载解析之后执行(可能需要等待)。| ```warn header="没有脚本的页面应该也是可用的" From 22f0c5f5b2bea6849a0ec4499769e6e96f4bcc5c Mon Sep 17 00:00:00 2001 From: LeviDing Date: Tue, 11 Jun 2019 10:36:50 +0800 Subject: [PATCH 10/27] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=A9=BA=E8=A1=8C?= =?UTF-8?q?=E4=B8=8E=E8=8B=B1=E6=96=87=E7=89=88=E6=9C=AC=E4=BF=9D=E6=8C=81?= =?UTF-8?q?=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 2-ui/5-loading/02-script-async-defer/article.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index acde3f6426..086911700f 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -1,3 +1,4 @@ + # Script 标签属性:async, defer 现代脚本中,脚本往往比 HTML 更 “重”:它们的大小通常更大,处理时间也更长。 @@ -88,6 +89,7 @@ Defer 脚本保持他们的相对顺序,就像常规脚本一样。 `defer` 属性会忽略没有 `src` 属性的 ` ``` + ## 动态脚本(Dynamic scripts) 我们也可以使用 JavaScript 动态地添加脚本: @@ -157,6 +161,7 @@ document.body.append(script); 例如,这里我们添加了两个脚本。在没有设置 `script.async=false` 时,它们执行顺序为加载优先顺序(即 `small.js` 可能先运行)。但是当设置了 `script.async=false` 后,脚本执行顺序就是它在文档中的顺序: + ```js run function loadScript(src) { let script = document.createElement('script'); @@ -170,6 +175,7 @@ loadScript("/article/script-async-defer/long.js"); loadScript("/article/script-async-defer/small.js"); ``` + ## 总结 `async` 和 `defer` 属性有一个共同点:它们都不会阻塞页面的渲染。因此,用户可以立即阅读并了解页面内容。 From 4f4e8dec73d624ec451a43d0a3efb222d14fed43 Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 11:01:56 +0800 Subject: [PATCH 11/27] Update 2-ui/5-loading/02-script-async-defer/article.md --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index 086911700f..1ea754301b 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -118,7 +118,7 @@ Defer 脚本保持他们的相对顺序,就像常规脚本一样。 1. 页面内容立刻显示出来:`async` 脚本不会阻塞页面加载。 2. `DOMContentLoaded` 可以在 `async` 之前或之后触发,不能保证谁在前谁在后。 -3. Async 脚本不会等待彼此。一个小的脚本 `small.js` 放在后面,但是可能会比 `long.js` 这个长脚本先加载完成,所以尽管 `small.js` 在后面,但是它可能先运行。这一行为被称为 “加载优先” 顺序。 +3. Async 脚本不会等待彼此。一个小的脚本 `small.js` 放在后面,但是可能会比 `long.js` 这个长脚本先加载完成,所以尽管 `small.js` 在后面,但是它可能先运行。这一行为被称为“加载优先(“load-first” order)”顺序。 当我们将独立的第三方脚本集成到页面的时候,此时采用异步加载方式是非常棒的:计数器,广告等等,因为它们不依赖于我们的脚本,同样我们的脚本也不应该等待它们加载完成: From 59ce917536b73aed2b479337dab4738fe68b56b7 Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 11:02:09 +0800 Subject: [PATCH 12/27] Update 2-ui/5-loading/02-script-async-defer/article.md --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index 1ea754301b..edf5db3b5e 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -144,7 +144,7 @@ document.body.append(script); // (*) 这也就是说: - 它们不会等待其他内容,其他的内容也不会等待它们。 -- 先加载完成的脚本先运行(“load-first” order) +- 先加载完成的脚本先运行(”加载优先“ 顺序) 我们可以通过将 `async` 属性显示修改为 `false` 来将加载优先顺序修改为文档顺序(就像常规脚本一样): From 6b1eec59576d94f37aa623a2b36bc20f79ccfe8b Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 11:03:27 +0800 Subject: [PATCH 13/27] Update 2-ui/5-loading/02-script-async-defer/article.md --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index edf5db3b5e..aaada74721 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -192,7 +192,7 @@ loadScript("/article/script-async-defer/small.js"); 因此,用户可以阅读这个页面内容,但是一些图形组件可能没有准备完成。 -所以,这就需要在页面适当位置添加 “加载” 进度指示,禁用无效的按钮,以清楚地向用户显示什么准备好了什么没有准备好。 +所以,这就需要在页面适当位置添加“加载”进度指示,禁用无效的按钮,以清楚地向用户显示什么准备好了什么没有准备好。 ``` 在开发中,通常在脚本需要整个 DOM 和/或它们相对执行顺序很重要的时候,此时使用 `defer` 属性。而当脚本之间互相独立,比如计数器或者广告,并且它们相对执行顺序不重要的时候,此时使用 `async` 属性。 From 17b12a9c1eeab3146d18769663baea2c787f70c4 Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 11:03:45 +0800 Subject: [PATCH 14/27] Update 2-ui/5-loading/02-script-async-defer/article.md --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index aaada74721..873434aefd 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -195,4 +195,4 @@ loadScript("/article/script-async-defer/small.js"); 所以,这就需要在页面适当位置添加“加载”进度指示,禁用无效的按钮,以清楚地向用户显示什么准备好了什么没有准备好。 ``` -在开发中,通常在脚本需要整个 DOM 和/或它们相对执行顺序很重要的时候,此时使用 `defer` 属性。而当脚本之间互相独立,比如计数器或者广告,并且它们相对执行顺序不重要的时候,此时使用 `async` 属性。 +在开发中,通常在脚本需要整个 DOM 文档或者脚本的相对执行顺序很重要的时候,使用 `defer` 属性。而当脚本之间互相独立,比如计数器或者广告,并且它们相对执行顺序不重要的时候,此时使用 `async` 属性。 From 25bd1809eed45fb0f39856e8445c00a88f5ff95b Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 11:04:55 +0800 Subject: [PATCH 15/27] Update 2-ui/5-loading/02-script-async-defer/article.md --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index 873434aefd..6fd4f879ac 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -144,7 +144,7 @@ document.body.append(script); // (*) 这也就是说: - 它们不会等待其他内容,其他的内容也不会等待它们。 -- 先加载完成的脚本先运行(”加载优先“ 顺序) +- 先加载完成的脚本先运行(“加载优先” 顺序) 我们可以通过将 `async` 属性显示修改为 `false` 来将加载优先顺序修改为文档顺序(就像常规脚本一样): From 15e56c8f4ac344c25d3bef3213252a1d3fb1258d Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 11:15:52 +0800 Subject: [PATCH 16/27] Update 2-ui/5-loading/02-script-async-defer/article.md Co-Authored-By: LeviDing --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index 6fd4f879ac..c298c823c5 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -1,7 +1,7 @@ # Script 标签属性:async, defer -现代脚本中,脚本往往比 HTML 更 “重”:它们的大小通常更大,处理时间也更长。 +现代的网站中,脚本往往比 HTML 更“重”:它们的大小通常更大,处理时间也更长。 当浏览器加载 HTML 时遇到 `` 标签,浏览器就不能继续构建 DOM。它必须立刻执行此脚本。对于外部脚本也是一样的 ``:浏览器必须等脚本下载,执行结束后才能处理剩余的页面。 From f02eb03a939668bbbfb160585ee92deea98deaca Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 11:16:34 +0800 Subject: [PATCH 17/27] Update 2-ui/5-loading/02-script-async-defer/article.md Co-Authored-By: LeviDing --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index c298c823c5..ef0ce5d00e 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -3,7 +3,7 @@ 现代的网站中,脚本往往比 HTML 更“重”:它们的大小通常更大,处理时间也更长。 -当浏览器加载 HTML 时遇到 `` 标签,浏览器就不能继续构建 DOM。它必须立刻执行此脚本。对于外部脚本也是一样的 ``:浏览器必须等脚本下载,执行结束后才能处理剩余的页面。 +当浏览器加载 HTML 时遇到 `` 标签,浏览器就不能继续构建 DOM。它必须立刻执行此脚本。对于外部脚本 `` 也是一样的:浏览器必须等脚本下载完,并执行结束,之后才能继续处理剩余的页面。 这会导致两个重要的问题: From 7c9fdddef9ea50078810b6dd8f2f1bc0682b63d3 Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 11:16:50 +0800 Subject: [PATCH 18/27] Update 2-ui/5-loading/02-script-async-defer/article.md Co-Authored-By: LeviDing --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index ef0ce5d00e..fcfef3d0f3 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -8,7 +8,7 @@ 这会导致两个重要的问题: 1. 脚本不能访问到位于它们下面的 DOM 元素,因此,脚本不能给它们添加事件等。 -2. 如果页面顶部有一个庞大的脚本,它会 “阻塞页面”。在脚本下载并执行结束前,用户都不能看到页面内容: +2. 如果页面顶部有一个庞大的脚本,它会“阻塞页面”。在脚本下载并执行结束前,用户都不能看到页面内容: ```html run height=100

...content before script...

From fb2629cb48d90a2a32548843b0acf13d8cd0a203 Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 11:17:07 +0800 Subject: [PATCH 19/27] Update 2-ui/5-loading/02-script-async-defer/article.md Co-Authored-By: LeviDing --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index fcfef3d0f3..8dd41c7e65 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -15,7 +15,7 @@ - +

...content after script...

``` From 073e4c37e0305d3565ab20856c64ee87daab113d Mon Sep 17 00:00:00 2001 From: lycheeEng Date: Tue, 11 Jun 2019 11:17:36 +0800 Subject: [PATCH 20/27] Update 2-ui/5-loading/02-script-async-defer/article.md Co-Authored-By: LeviDing --- 2-ui/5-loading/02-script-async-defer/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md index 8dd41c7e65..73a7f388c8 100755 --- a/2-ui/5-loading/02-script-async-defer/article.md +++ b/2-ui/5-loading/02-script-async-defer/article.md @@ -31,7 +31,7 @@ 但是这样的方案绝非完美。例如:浏览器只有在下载完整的 HTML 文档后才会注意到脚本(并且开始下载它)。对于长的 HTML 文档来说,这样的延迟必须引起注意。 -对于网络连接很快的人来说,这不值一提。但是这个世界上仍然有很多地区的人们他们使用很慢的网络连接,并且使用远非完美的移动互联网。 +对于网络连接很快的人来说,这不值一提。但是这个世界上仍然有很多地区的人们他们使用很慢的网络连接,并且使用着远非完美的移动互联网。 幸运的是,这里有两个 `