“This is the 15th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

In the past, we saw that a large number of event triggers in a short period of time would cause the browser to freeze and waste browser performance. So why would event triggers cause the page to block? Is it really the case that too many events are being fired that cause the page to block?

Note: The test case for this article is from Chrome

How to count cards?

What is a card during page run? If from the user’s point of view, that click a button does not respond, count card; The drop-down page did not move, calculate card; Images stopped loading, GIF images did not turn, animation stopped, calculate card; In short, the page is not able to make the right action according to the user, even if the page is blocked. In this paper, the page is blocked. Will the high intensity of the event trigger the page?

Interaction failure

As for the browser running, JS thread and GUI rendering thread are mutually exclusive. We usually say that the page is stuck, that is, it does not move or respond. Usually, JS thread is occupied in a high intensity. When the event is triggered, it will stuff the task into the task queue, such as the callback of the click event, and then the JS engine will read the task queue and execute JS. If your JS execution takes a long time, it will block the rendering of the page. If it is triggered frequently, it will block the page forever. So to prove the above conjecture (for now), give it a try

First, verify that clicking the button does not respond, which corresponds to JS not executing in time, listening to the mouseenter event (because the click event is not visible in the GIF), and using an idled for loop to simulate the high-intensity OPERATION of JS, the code is as follows

<! DOCTYPEhtml>
<html>
  <body>
    <div onmouseenter="add()"></div>
  </body>
  <script>
    / / 9 0
    // Click once to print once
    let num = 0;
    function add() {
      console.log(++num);
      for (let i = 0; i < 3000000000; i++) {}
    }
  </script>
  <style>
    div {
      width: 100px;
      height: 100px;
      background-color: black;
    }
  </style>
</html>
Copy the code

The results are as follows

The mouseEnter event is triggered three times. The first time it prints immediately, and the second time it prints. This means that JS execution does block the page, but it is blocking the interaction, causing JS execution to be delayed. Because JS threads in a second event trigger in the execution of JS for the first time, also note that there are small details, here the thread, in fact just page there is a thread, the thread is trigger events, from just a printed 3 times instead of once or twice, that event trigger thread it is a separate thread, Similar to download thread, not mutually exclusive with JS thread, when we JS thread in the execution of the time, the event can also be triggered normally

Here also back to the topic, high frequency trigger is the event will block page, from the point of this kind of circumstance, because independent event triggers thread, so JS thread will continue to perform are tasks in the task queue, if happen to this task is to calculate the complexity JS, takes a long time, such as the response after the click of a button and then click the, JS execution will be delayed and eventually the entire page interaction will fail

In this case, you can use the Web worker to open another thread to deal with it. If you are interested, go to Baidu

Animation class blocking

JS delayed execution is a kind of blocking of interaction type, so JS thread is mutually exclusive with GUI thread, and the event is triggered at a high frequency, it is also bound to continuously execute JS, so such as GIF and animation involving GUI thread will not be blocked, that is to prove that JS thread and GUI thread mutually exclusive, Use the above example as a template and add an IMG GIF

<! -... -->
<div onmouseenter="add()"></div>
<p>-- Dividing line --</p>
<img src="http://localhost:8000/gif.gif" />
<! -... -->
Copy the code

The results are as follows

I was a little surprised by this result, because I had read an article before that JS execution would block the loading of giFs, but this is not true in practice, is it because we use different browsers? At least Chrome’s computational complexity JS doesn’t block giFs from loading

So excluding the effect of event triggering on GIF loading, next we will see if CSS animation will be affected by JS, or the example above as a template, plus a left-to-right animation

<! -... -->
<div onmouseenter="add()"></div>
<p>-- Dividing line --</p>
<div class="animation"></div>
<! -... -->
<style>
  / *... * /

  @keyframes move {
    from {
      left: 0;
    }

    to {
      left: 100%; }}.animation {
    position: absolute;
    animation: move 5s linear infinite;
  }
</style>
Copy the code

With the familiar 3 mouseEnter events, our animation will eventually wait for JS execution to complete before it can proceed, so we can conclude that in the case of CSS animations on the page, If the high frequency of events is triggered and the callbacks triggered are computations to complex JS, the page will block (animation will not work)

conclusion

  1. The frequent firing of events is not the real cause of the page blocking, because the event firing thread is an independent thread
  2. Whether the event triggers the JS callbackComputational complexityIs it possible that a long task is the real cause of the blocked page