Execution sequence and Optimization of click events

< H2 > scene: < / H2 >

when you click button, add a class, to li and then execute a for loop

< H2 > Code < / H2 >
    <script>
        $(".btn").on("click", function () {
            $("li").addClass("add")
            for (var i = 0; i < 100000; iPP) {
                console.log(i)
            }
        });
    </script>
< H2 > question < / H2 >

1. Find that every time you execute this click event, you must finish executing for before you can add class, to li. Why?

2. Every time you execute click, the loop inside is indispensable. How to optimize this loop?

May.22,2021

first of all, you have to understand that the browser is not a whole, it has several modules, JS runtime (V8), rendering engine (blink), main thread (processing plug-ins, automatic updates, etc.), so you operate DOM, in JS will not directly reflect to DOM, but by V8 to notify blink.

re-rendering takes a lot of time, especially if you need relayout and repaint. So, to avoid a.classList.add ('add') -> a.classList.remove (' add') -> a.classList.add ('add') -> a.classList.remove (' add') ->. This repeated cycle wastes rendering efficiency. The browser will cache your changes to DOM. After the execution of the current JS stack, you will modify it at once, and then relayout + repaint at one time.

so you will see that although you have styled a DOM node in JS, you have only modified its image in V8, and its ontology has not changed. It doesn't change until the JS is finished.

the second question, I think, is your implementation. As a front end, it is taboo to allow the time of an operation to be perceived by users. If this operation takes a long time, on the one hand, you can use setTimeout to put it to the next time node, as said upstairs; on the other hand, you should carefully consider whether it is really necessary to run such a long cycle from an algorithm point of view.


  1. the action of jquery operation dom is asynchronous and must wait until the current Synchronize command console has been fully executed.
  2. if in the logic in click, the previous action of adding add to li is not affected by the following loop, then you can wrap the loop with setTimeout and execute asynchronously.

      <script>
          $('.btn').on('click', function () {
              $('li').addClass('add');
              setTimeout(function() {
                  for (var i = 0; i < 100000; iPP) {
                  console.log(i)
                  }
              }, 0);
    
          });
      </script>
Menu