事件循环 - 无限循环不会在 Chrome 中停止渲染管道,但它会在 Firefox 中停止

Event loop - Infinte loop won't stop rendering pipeline in Chrome but it will on Firefox

在下面的代码笔中,"stop earth" 按钮启动了一个无限循环。

我原以为循环会阻止浏览器启动渲染管道,但令我惊讶的是 Chrome gif 继续顺利进行。

在 Firefox 上测试时,gif 会立即停止。

https://codepen.io/amirnamdar-the-scripter/pen/NWPeRNY

<script> 
function stop() {
while (true);
}
</script>

<body>
    <h1> Think you can stop the earth from spinning? </h1>
    <h2>Hit the button</h2>

    <button onclick="stop()" > stop earth </button>
    <img src="https://media.giphy.com/media/ux6AQI6MBwGqY/giphy.gif" width="480" height="270">
</body>

我认为这可能与不同引擎中事件循环的不同实现有关。

我很好奇 V8 与 SpiderMonkey 的不同之处导致了这种差异。

谢谢

这个实验告诉您的是,在 Chrome 中,JavaScript 执行和 gif animation/drawing 发生在不同的线程(甚至可能是不同的进程)上。仅仅因为 JavaScript 是单线程并不意味着浏览器的其余部分也必须在同一个线程上 运行。您的无限循环仍将阻止处理其他事件,因为控制永远不会 returns 到事件循环——但事件循环是一个 JavaScript 概念,gif 不需要关心它。

这是一个更新的实验来证明:

<head>
<script>
var stop_requested = false;
function loop() {
  while (!stop_requested) {}
}
function stop() {
  alert('requesting stop');
  stop_requested = true;
}

</script>
</head>
<body>
  <button onclick="loop()">interruptible loop</button>
  <button onclick="stop()">request stop</button>
</body>

如果您单击第一个按钮,将启动一个可中断的无限循环,这将阻止第二个按钮的事件处理程序(您永远不会看到警告框)。

根据 Jeff 在下面的评论,我想用他的回答来结束这个问题:

they moved gif frame rendering to the compositor thread