【问题标题】:Does Iframe Creates separate execution context?iframe 是否创建单独的执行上下文?
【发布时间】:2019-01-10 17:12:17
【问题描述】:

我正在用 js 编写一个 html 解析器,它处理和操作很多节点。

我想分摊开销,以免导致 UI 冻结。

我考虑过使用 web Worker,但它没有 DOM 访问权限,所以目前我在循环中使用setTimeout(0) 来不冻结 UI,但我考虑创建多个空白 iframe 并使用它们的窗口上下文做这个任务。

我的问题是它是否真的被认为是一个单独的执行上下文并与主执行上下文并行运行,或者它仍然会冻结主 UI?

【问题讨论】:

  • 如果您使用 iframe 作为单独的执行上下文,则必须使用消息在上下文之间进行通信。为什么不对 worker 做同样的事情,只在主线程中留下 DOM 特定的代码?
  • @MTCoster 因为空白 iframe(无 src)内的代码可以访问主 dom
  • 我没有意识到这一点。但问题仍然存在,为什么不能将特定于 DOM 的代码与处理器密集型代码分开并使用消息将它们连接起来?
  • @MTCoster 我可以,但是如果 iframe 拥有与 web worker 相同的好处,那么使用 iframe 会容易得多。
  • @StriplingWarrior 不完全是,如果我在 iframe 中运行负载密集型代码,它仍然无法回答我的问题,主 UI 是否会继续并行加载

标签: javascript


【解决方案1】:

这实际上取决于浏览器。例如,由于计算开销,移动浏览器不太可能将不同的嵌入式 iframe 放在单独的线程/进程中。

但是从 2021 年初开始,现在有了(奇怪的名字)Origin-Agent-Cluster 标头,它允许您明确地为 iframe 请求专用资源。它目前在 Chrome (88+) 上得到支持,并得到 Mozilla 和 Safari 的好评。

Origin-Agent-Cluster 是一个新的 HTTP 响应头,它指示浏览器阻止同站点跨域页面之间的同步脚本访问。浏览器也可能使用 Origin-Agent-Cluster 来暗示您的源应该获得自己的独立资源,例如专用进程。

[...] 例如,如果 https://customerservicewidget.example.com 期望使用大量资源进行视频聊天,并将嵌入到整个 https://*.example.com 的各个来源,则维护该小部件的团队可以使用 Origin-Agent-Cluster header 以尝试减少它们对嵌入器的性能影响。

要使用 Origin-Agent-Cluster 标头,请将您的 Web 服务器配置为发送以下 HTTP 响应标头:Origin-Agent-Cluster: ?1 ?1 的值是布尔真值的结构化标头语法。

更多详情:https://web.dev/origin-agent-cluster/

【讨论】:

    【解决方案2】:

    是的,iframe 中的 JavaScript 在其自己的线程中运行,它不会阻塞父窗口。它大多像一个单独的窗口或选项卡,主要区别在于它是在父框架内渲染的,并且可以使用window.parent 引用父级。

    【讨论】:

    • 似乎 iframe 确实会影响主 ui,如果我插入一个空白 iframe 并注入一个只会循环 5 秒的脚本,主 ui 也会冻结,所以我在做什么错误的? iframe 需要位于不同的来源?
    • 正如@avidahan 提到的,这个答案是不正确的(至少对于 Chromium 75)。 iframe 中的无限循环(同域或跨域 - 没关系)将阻塞父窗口的主线程。如果您不使用rel="noopener" 属性,即使是使用target="_blank" 打开的链接也会明显阻止打开器窗口。我想知道 iframe 是否有 noopener 的等价物:stackoverflow.com/questions/56589672/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    • 2019-01-16
    • 2010-09-16
    相关资源
    最近更新 更多