SetTimeout, the front-end engineer is bound to deal with a function. It looks very simple and earthy. It has a very unusual name--the timer. Let the young I naïve thought that I can manipulate the future. But I do not know the simplicity of the hidden secret. I remember the first time I used this function, I naively thought that it is the JS implementation of multi-threading tools. It was a game of battle with a tank battle. But as it went further and farther along the way, the understanding began to change. It seemed to begin to veil, and there was always some strange performance that I could not fathom. Finally, my patience is exhausted. , determined to rip its mask off, to find out what it was.
To say the origin of settimeout, we have to start with its official definition. That's what the Web is all about.
The SetTimeout () method is used to call a function or evaluate an expression after a specified number of milliseconds.
To see such a note, we understand that it is a timer, we set the function is an "alarm clock", the time it will go to execute. But smart you can not help but have such a doubt, if it is settimeout (fn,0) it? By definition, will it execute immediately? Practice is the only criterion for testing truth, let's take a look at the following experiment
<! DOCTYPE html>
This is a very simple experiment, if settimeout (0) will be executed immediately, then the result here should be 1->2>3. But the actual result is 1->3->2. This shows that settimeout (0) is not executed immediately. At the same time, let us feel very strange about settimeout's behavior.
JS engine is single-threaded executionLet's put the above problem in the first place. From the JS language design to see if you can find clues.
We find that the JS language design is a very important point is that JS is not multi-threaded. JS engine execution is single-threaded execution. This feature has been bothering me for a long time, I do not understand that since JS is a single-threaded, then who is to time the timer? who sent the AJAX request? I fell into a blind spot. JS is the same as the browser. We are used to executing code in the browser, but ignoring the browser itself. JS Engine is single-threaded, but the browser can be multi-threaded, JS engine is just a browser thread. Timer timer, network request, Browser rendering, and so on. It's all done by different threads. Accreditations, we still see an example
<! DOCTYPE html>
Isend is true by default and is a dead loop in while. The last alert is not executed. I added a timer and changed the Isend to false after 1 seconds. If the JS engine is multithreaded, then after 1 seconds, the alert will be executed. However, the reality is that the page will die forever. The alert was not executed. This is a good proof that settimeout is not used as a multithreaded operation. JS engine execution is single threaded.
Event loopFrom the above experiment, we are more puzzled, what exactly did settimeout do?
I still have to find the answer from the design of JS language.
JS engine single-threaded execution, it is an event-driven language. Its execution sequence follows a mechanism called the event queue. We can see that the browser has a variety of threads, such as event triggers, network requests, Timers and so on. The connection of threads is event-based. The JS engine processes the code that is related to other threads, distributes it to other threads, and when they are done, the JS engine is required to add a task to the event queue. In this process, JS does not block the code waiting for other threads to finish, and the Add Event task tells the JS engine to perform the action after the other threads have finished executing. This is the asynchronous programming model of JS.
So we go back and look at settimeout (0). When the JS code executes here, it will open a timer thread, and then proceed to the following code. The thread inserts a task into the event queue after the specified time. settimeout (0) The operation inside will be placed after all the main thread tasks. This explains why the first experimental result is 1->3-2.
This shows that the official definition of settimeout is deceptive. A new definition should be given:
Within the specified time, the task is placed in the event queue, waiting for the JS engine to be idle and executed.
The JS engine is mutually exclusive with the GUI engineSpeaking of this, we have to say that another browser engine---GUI rendering engine. In JS the rendering operation is also asynchronous. For example, the DOM operation code generates a task in the event queue, and JS executes the task to invoke the GUI engine rendering.
JS language set JS engine is mutually exclusive with the GUI engine, that is, the GUI engine will block the JS engine calculation when rendering. The reason is very simple, if JS changes the DOM when the GUI is rendered, it will cause the rendering to be out of sync. We need a deep understanding of the JS engine and GUI engine relationship, because this is closely related to our usual development, we will encounter some very wonderful rendering problems. See this example
<! DOCTYPE html>We want to see every process of computation, we perform a DOM operation at the beginning of the program, the calculation, and the end, inserting a string representing the current state, not calculating yet. and calculating .... and calclation done. The calculation is a time-consuming 3-heavy for loop. When the settimeout is not used, the result of the execution is a direct jump to calclation done by not calculating yet. This is obviously not what we want. The result is the single-threaded mechanism of the event loop of JS. Dom operations are asynchronous, The For loop calculation is synchronous. Asynchronous operations are deferred until the synchronization is evaluated. That is, the code executes in a changed order. Calculating .... and calclation done DOM operations are placed behind the event queue and are immediately followed together, resulting in dropped frames. Unable to react in real time. This example also tells us that in the case of real-time feedback, such as rendering, and other related synchronized code, or synchronization, Either asynchronously can guarantee the execution order of the code. In JS, you can only make synchronous code asynchronous. That is, add settimeout to the for calculation.
The role of settimeout (0)Depending on the implementation of the different browsers, the minimum time interval defined by the HTML5 is 4 milliseconds. Using settimeout (0) uses the minimum time interval supported by the browser. So when we need to put some operations into the next frame, we usually use settimeout (0) to hack.
RequestanimationframeThis function is similar to settimeout, but it is specifically animated. SetTimeout is often used to animate. We know that the animation reaches 60 frames, The user will not be able to perceive the screen spacing. Each frame is about 16 milliseconds. The Requestanimationframe frame rate is exactly the same frequency. In addition to settimeout, there are some advantages:
- Requestanimationframe will centralize all DOM operations in each frame, complete in one redraw or reflow, and redraw or reflow intervals closely follow the browser's refresh rate, typically 60 frames per second, about 16 milliseconds per frame.
- In hidden or invisible elements, requestanimationframe will not redraw or reflow, which of course means less cpu,gpu and memory usage.
- But its advantage over Settimeout/setinterval is that it is an API specifically provided by the browser, which automatically optimizes the invocation of the method at run time and automatically pauses the animation if the page is not active, saving CPU overhead.
Summarize:
- The kernel of the browser is multi-threaded, and they mate with each other in the kernel to keep in sync, and a browser implements at least three resident threads: JavaScript engine thread, GUI render thread, browser event trigger thread.
- JavaScript engines are executed on a single thread based on event-driven. JS engine has been waiting for the task queue in the arrival of the task, and then to deal with, the browser whenever there is only one JS thread running JS program.
- The thread executes when the interface needs to be redrawn (Repaint) or because an operation causes reflux (reflow). However, it is important to note that the GUI rendering thread is mutually exclusive to the JS engine, and when the JS engine executes, the GUI thread is suspended, and the GUI update is saved in a queue until the JS engine is idle and executed immediately.
- When an event is triggered, the thread adds the event to the end of the queue to be processed and waits for the JS engine to process. These events can come from code blocks currently executing by the JavaScript engine, such as settimeout, other threads from the browser kernel such as mouse clicks, Ajax asynchronous requests, and so on, but because of the JS single-threaded relationship all of these events are queued for the JS engine to process.
Tags: settimeout, eventloop, GUI, async
JS SetTimeOut ()