防止长时间运行的 javascript 锁定浏览器

IT技术 javascript
2021-02-01 03:07:17

我有 JavaScript,它执行大量计算以及从/向 DOM 读取/写入值。该页面很大,因此这通常最终会在 CPU 使用率为 100% 的情况下锁定浏览器长达一分钟(有时使用 IE 会更长)。

是否有任何关于优化 JavaScript 以防止这种情况发生的资源(我能找到的只是如何关闭 Firefox 的长时间运行的脚本警告)?

6个回答

如果你可以将你的计算算法变成可以迭代调用的东西,你可以通过使用带有短超时值的setTimeout频繁的间隔释放对浏览器的控制

例如,这样的事情......

function doCalculation()
{
   //do your thing for a short time

   //figure out how complete you are
   var percent_complete=....

   return percent_complete;
}

function pump()
{
   var percent_complete=doCalculation();

   //maybe update a progress meter here!

   //carry on pumping?
   if (percent_complete<100)
   {
      setTimeout(pump, 50);
   }
}

//start the calculation
pump();
@Andy YessetTimeout与 0 也会有帮助。请参阅此问题的一些答案
2021-03-13 03:07:17
你知道如果你使用它是否仍然有效setTimeout(pump, 0)吗?或者这可能会继续抢占响应鼠标输入的浏览器代码,更新进度表或其他 DOM 元素?
2021-03-17 03:07:17

使用超时。

通过将循环的内容放入单独的函数中,并从 setTimeout() 以 50 左右的超时时间调用它们,javascript 将放弃对线程的控制并在一段时间后返回,从而允许 UI 获得顺便拜访。

有一个很好的workthrough这里

前段时间我写了一篇关于浏览器内性能的博客,但让我在这里为您总结一下与 DOM 相关的内容。

  • 尽可能不频繁地更新 DOM。对内存中的 DOM 对象进行更改,并将它们仅附加到 DOM 一次。
  • 使用内部HTML。在大多数浏览器中,它比 DOM 方法更快。
  • 使用事件委托代替常规的事件处理。
  • 知道哪些电话是昂贵的,并避免它们。例如,在 jQuery 中,$("div.className") 将比 $("#someId") 更昂贵。

然后还有一些与 JavaScript 本身相关的:

  • 尽量少循环。如果您有一个函数收集 DOM 节点,另一个函数处理它们,那么您将循环两次。相反,将匿名函数传递给收集节点的函数,并在收集节点时处理节点。
  • 尽可能使用本机功能。例如,forEach 迭代器。
  • 使用 setTimeout 让浏览器偶尔喘口气。
  • 对于具有幂等输出的昂贵函数,请缓存结果,以便您不必重新计算它。

我的博客上还有一些(上面的链接)。

这仍然有点前沿,但 Firefox 3.5 有这些叫做 Web Workers 的东西,但我不确定它们在其他浏览器中的支持。

Resig 先生在这里有一篇关于它们的文章:http : //ejohn.org/blog/web-workers/

模拟退火可能是它的最简单的例子,如果你会发现Firefox的纺纱标识不冻结,当工作线程正在做他们的请求(因此不冻结浏览器)。

我将此标记为适度......我们会看到会发生什么。
2021-03-18 03:07:17
好点,当然现在应该是最重要的。无论你做什么,使用 setTimeout 对我来说听起来都很棘手,除非你真的需要超时。如果您现在在 Chrome Windows 上访问 codepen.io 并执行复杂度为 O(N!) 的算法,例如查找字符串 "ABCDEFGHIJKLMNOP" 的所有排列,您的浏览器将锁定并变得无响应。在工作线程中,UI 保持自己运行。这显然是正确的答案。
2021-04-04 03:07:17

您可以尝试在线程中执行长时间运行的计算(请参阅JavaScript 和 Threads),尽管它们不是很可移植。

您也可以尝试使用一些 Javascript 分析器来查找性能瓶颈。Firebug支持分析 javascript。