gpt4 book ai didi

javascript - 同源 CPU 密集型 iframe 的单独事件循环

转载 作者:行者123 更新时间:2023-12-04 04:27:37 28 4
gpt4 key购买 nike

假设我有一个 CPU 密集型 iframe。
它与父页面在同一个域中,因此不适用跨域,因此它共享父页面的事件循环。

是否可以为 iframe 提供一个单独的 JS 上下文(包括一个单独的事件循环),这样它就不会阻塞父级的 UI?

设置sandbox iframe 的属性标签并不能解决这个问题,尽管 docs声明 iframe 将被视为来自“唯一来源”。

这个问题是假设的/概念的。我没有一个真正的用例。只是好奇。
我在徘徊像 JSFiddle 这样的网站如何运行用户的代码,并且显然它从来自不同域的 iframe 运行(在 JSFiddle 的情况下为 jshell.net)。

最佳答案

JSFiddle 之类的服务如何在不同的事件循环中运行用户代码?
他们没有解决实际问题,他们只是通过使用跨域 iframe 来解决问题。
例如,这可以很容易地在 StackBlitz 上看到,它们为每个执行环境创建一个子域。
在 JSFiddle 上,起初这有点难以看穿,因为他们的 iframe 没有 src属性集。但是,iframe 绑定(bind)到一个表单,该表单最终成为另一个跨域 iframe。
解决方法 - 网络 worker
正如其他人正确提到的那样,您可以使用网络 worker 来生成新的 JS 上下文,并在那里运行一些繁重的计算。
这是可行的,因为网络 worker 在独立的线程中运行( MDN )。
解决方法 - 以较小的 block 运行代码
正如其他人也提到的那样,您可以通过以较小的 block 运行代码来提高性能。举个例子:

const array = [ ... ]; // array with hundreds of items
const result = [];

const stepByStepCalculation = () => {
if (array.length) {
result.push(doExpensiveCalculation(array[0]));
array.shift();
requestAnimationFrame(stepByStepCalculation);
}
}

stepByStepCalculation();
现在,在事件循环的每次迭代之后,我们数组的一项正在被处理 - 一步一步。
此外,使用 requestAnimationFrame而不是 setIntervalsetTimeout有一个优势,它会在每次事件循环迭代之后被调用,而不是在 ~4ms 之后,这使得它更快。
我们的解决方法的问题
我们的解决方法只有在我们的昂贵任务不需要不断地从 DOM 中读取时才有效。
这是个大问题 ,如果我们的同源 iframe 有昂贵的 JavaScript 动画,它会严重干扰并可能导致 UI 滞后。
总结
将计算移到工作线程中,或逐步进行以减少负载。
但是,对于您的主要问题,我们无法为同源 iframe 创建单独的 JS 上下文(截至目前)。在线 JS shell 通过使用跨域 iframe 解决了这个问题。
如果我们能以某种方式在合成器或光栅线程中运行 JavaScript 代码,将会很有趣,因为它们应该可以访问我们的 DOM,这与 web worker 不同。

关于javascript - 同源 CPU 密集型 iframe 的单独事件循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24362727/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com