1

In the following codepen the "stop earth" button initiates an infinite loop.

I was expecting that the loop will prevent the browser from initating the rendering pipieline but I was surprised to see that in Chrome the gif continues smoothly.

When testing this on Firefox the gif stops immediately.

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>

I assume that this might have something to do with the different implementations of the event loop in the different engines.

I'm curious about what V8 does differently than SpiderMonkey that results in this difference.

Thanks

amirNamdar
  • 31
  • 7
  • Nowhere in the ecmascript spec does it say, that the animation of gifs has to be on the same thread as the javascript, or that it could only occur at certain update phases of JS. Therefore, it depends on what the browser does. Similarly, you can still close the tab on most browsers, and the entire browser doesn't crash, because e.g. on chrome, each tab has its own process. – ASDFGerte Jan 21 '20 at 18:09

2 Answers2

1

Following Jeff's comment below I'd like to conclude the question with his answer:

they moved gif frame rendering to the compositor thread

amirNamdar
  • 31
  • 7
0

What this experiment tells you is that in Chrome, JavaScript execution and gif animation/drawing are happening on separate threads (or possibly even separate processes). Just because JavaScript is single-threaded doesn't mean that the entire rest of the browser also has to run on that same thread. Your infinite loop will still prevent additional events from being processed, because control never returns to the event loop -- but the event loop is a JavaScript concept, and gifs don't need to care about it.

Here is an updated experiment to demonstrate that:

<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>

If you click the first button, an interruptible endless loop is started, which will block the second button's event handler (you'll never see the alert box).

jmrk
  • 34,271
  • 7
  • 59
  • 74
  • Thanks This wasn't the case in 2018 https://www.youtube.com/watch?v=cCOL7MC4Pl0&t=617s 09:48 Do you have more information about this change, shouldn't gif rendering be part of the event loop? is that the case for gifs only? – amirNamdar Jan 21 '20 at 21:08
  • I have no further information on what specifically might have changed. Browsers keep changing all the time as their respective development teams improve them. As stated before, there is no reason why gif rendering would *have to* be on the event loop -- playing an existing gif's animation is not a change to the DOM, so it might be implemented such that it's done by the main thread, or it might not. – jmrk Jan 22 '20 at 09:52
  • 1
    Yeah, they kinda spoiled the demo in my talk! I think we moved gif frame rendering to the compositor thread, so it doesn't matter if the main thread is blocked. – JaffaTheCake Jan 23 '20 at 11:56