What about the shock? ! Do not allow setInterval to control image switching in seamless scrolling graphs? , and then to the others in the project to promote the operation, when a colleague asked principle, I will put a B, said that the priority of the CSS animations in micro tasks, such as CSS after the animation has been completed to carry out a macro task (will come to the conclusion that because I didn’t effect, with micro tasks using setTimeout is ok), In retrospect, I felt guilty, so I started this article

The connection between UI rendering in the browser and the JS engine

To do this, we need to understand the concepts of task queues and event loops

Task queue

All tasks can be divided into synchronous tasks and asynchronous tasks. Synchronous tasks, as the name implies, are immediately executed tasks. Generally, synchronous tasks are directly executed in the main thread. Asynchronous tasks are asynchronously executed tasks, such as Ajax network requests and setTimeout timing functions. Asynchronous tasks are coordinated through the mechanism of task Event Queue.

Event loop

Synchronous and asynchronous tasks enter different execution environments. Synchronous tasks enter the main thread (main execution stack) and asynchronous tasks enter the Event Queue. If the task execution in the main thread is empty, the Event Queue will read the corresponding task and push the main thread to execute it. The repetition of this process is called an Event Loop (also called an Event Loop). It is shown as follows:

In an event cycle, each operation is called tick. The task processing model of each tick is complex, and its key steps can be summarized as follows:

  1. Select the first macro task to queue in this tick and execute it if any
  2. Check whether there are microtasks, if so, continue to execute until the microtask queue is empty
  3. To render the page
  4. Repeat the steps for the main thread

After knowing these can be seen, I pack to force before the content of the said is absolutely nonsense, it should be correct because UI rendering (also called GUI thread) with js engine (also called js thread mutex, only when the event loop of a macro after task execution, js engine hangs, UI rendering can enter into circulation, when after the rendering, The event loop begins to introduce and execute the next macro task

So let’s do a couple of simple examples to make it easier to understand. So let’s do a color change, let’s make the page flash red

document.body.style.background = 'red';
document.body.style.background = 'white';
Copy the code

The above code will definitely fail, and the background will be steadily white. Because both lines of code are synchronous tasks, it is impossible to insert a render task between them. At this point, one might think of setTimeout:

document.body.style.background = 'red';
setTimeout(function () {
    document.body.style.background = 'white';
},0)
Copy the code

If you put this code in F12, you can obviously see it flashing. However, the two Settings will be performed in different tasks. If a render task is inserted between the two tasks, the background will flash, and the render task is 1000/60ms once (assuming your monitor refreshes at 60Hz), how do you know that the browser will be inserted in between the two tasks? So the above code will only work in a few cases. Fortunately, the browser to a proprietary API — window. RequestAnimationFrame, so that the browser before the next redraw to perform your operation

requestAnimationFrame(function () {
    document.body.style.background = 'red';
    requestAnimationFrame(function () {
        document.body.style.background = 'white'; })})Copy the code

Examples from actual work development

For example, the core code of the wheel cast diagram I wrote earlier is the following lines

requestAnimationFrame(function () {
    lists.classList.remove("is-animating")
    lists.style.transform = `translateX(The ${0}px)`;
    requestAnimationFrame(function(){
    	lists.classList.add("is-animating")
        const left = -current * width
        lists.style.transform = `translateX(${left}px)`; })})Copy the code

Translation into text is when the picture comes to the last one, remove the animation effect, and then move, after moving the animation effect, and then the whole rotation map will be very coherent

See article below: How do event loops affect page rendering? An in-depth understanding of the JavaScript event loop mechanism and when the rendering engine renders the UI