【问题标题】:Does inline javascript block the UI thread?内联 javascript 会阻止 UI 线程吗?
【发布时间】:2012-09-14 18:27:18
【问题描述】:

我在how external scripts block the UI thread 上阅读了这篇不错的文章,但我不清楚阻塞实际上是由于<script> 标记还是src='/myscript.js' src 属性的存在。

我的问题是内联 javascript(缺少 src 属性声明),例如:

<script type='text/javascript'> alert('am i blocking too?');</script>

或者这个:

<script type='text/javascript'> var php='<?=json_encode($myObj)?>';</script>

还阻塞 UI 线程?

【问题讨论】:

  • alert() 将阻止事情直到它被确认,无论你把它放在哪里。
  • 好的,如果我只是制作一些对象或做一些其他函数调用而不是提醒某些东西呢?也许您可以通过说明哪些阻止和哪些不阻止来回答这个问题?
  • 内联 JS 和 src 都会在遇到 AFAIK 时执行 JS 时阻塞 UI 线程。尝试在 PHP 中回显一个 JS 文件,头部有 5 秒的睡眠时间,页面在加载脚本之前不会呈现。
  • @FabrícioMatté,谢谢,这很有帮助,什么是 AFAIK?
  • 据我所知。我有一些测试服,不久前在SO的JS聊天中讨论过。

标签: javascript blocking nonblocking src ui-thread


【解决方案1】:

任何 JS 文件的加载或 任何 JS 的任何执行(无论是在外部文件中还是内联)都会阻塞 UI 线程。

&lt;script&gt; 标记的例外是异步加载,其中脚本将在后台异步加载和执行。

还有“延迟”加载(即defer 属性)告诉浏览器在页面的其余部分加载之前不要实际执行其中的 JS。

【讨论】:

  • 而延迟加载可以通过 HTML5 的async 属性或通过在 body 标记末尾动态附加脚本元素来实现。
  • @FabrícioMatté 实际上是 defer 属性。
  • 你忘了说这些属性不适用于内联脚本
  • @FabrícioMatté 我没有意识到现在有asyncdefer - 我已经更新了。
  • PHP 不会以任何方式影响脚本。您的浏览器只会看到回显的 HTML 和 JS,并将其解析到 DOM 树中。脚本在找到时执行,这意味着它将“阻塞” UI 线程。但是,如果您只是创建一个对象,该块将持续不超过几分之一毫秒(除了加载时间)。如果你想要不显眼的 JS,请将你的 JS 移动到 body 标记的底部,这是它们应该在的位置。
【解决方案2】:

web workers 之外,它们是他们自己的野兽,将 HTML 网页和相关的 Javascript 视为单线程。[1]

因此,如果 any javascript 正在页面上运行,则整个用户界面都会被阻止。 window.alert()window.confirm()window.prompt() 之类的东西会阻塞整个 UI,直到它们被清除,但即使是无限循环也会冻结浏览器窗口 [2] 直到它完成。

EDIT -- 基于 cmets 并编辑问题:

原始问题中提供的链接不是指 JavaScript 运行的 execution,而是 JavaScript 的 sync vs async 性质加载。我将举一个例子说明为什么会发生这种阻塞。

在过去的 Javascript 时代,函数 document.write() 是让 Javascript 与网页交互的唯一方法。因此,当网页遇到加载 Javascript 文件的请求时,浏览器必须暂停其他所有内容 - 以防 Javascript 文件使用 document.write 将某些内容注入流中。

在当今世界,这种情况并不多见,因此浏览器为页面设计者提供了一种方式来表达“我保证这个 Javascript 文件并不关心它的加载时间,它不会使用 document.write() 或还有什么棘手的。在完成之前您不必冻结。

这就是现代网络浏览器具有deferasync 属性的原因。

  1. Opera 很特别,但我们会忽略它。
  2. 或整个浏览器,视情况而定

【讨论】:

  • 我不认为 Opera 是个特例,因为它并没有真正做实质性的不同。同步 WebWorker 事件不是这个问题的一部分:-)
  • @Bergi -- Opera 不会像浏览器那样冻结 UI。事实上,在 Opera 下,您可以看到一些 DOM 操作在它们发生时实时发生。最初的问题不清楚 OP 询问的是哪种类型的阻止。
【解决方案3】:

alert() 或任何其他提示操作将阻塞线程,直到用户响应提示。不管他们在哪里……

更新(关于评论):

浏览器窗口解析 HTML 并使用单个线程运行 JS。因此,javascript 代码中任何需要时间才能完成的内容都会阻塞线程。无论它是什么。它可以是 @987654322 @ 或 AJAX Request 或其他任何东西..

【讨论】:

  • 也许您可以扩展您的答案,以阐明哪些阻止与哪些不阻止?简单地声明对象会阻塞吗?像这样->&lt;script&gt; var myObj='am i blocking?';&lt;/script&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
  • 2016-07-13
  • 1970-01-01
相关资源
最近更新 更多