In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-09 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces "what is the operating mechanism and principle of JavaScript". In daily operation, I believe that many people have doubts about the operating mechanism and principle of JavaScript. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "what is the operating mechanism and principle of JavaScript?" Next, please follow the editor to study!
What is the JavaScript parsing engine
To put it simply, a JavaScript parsing engine is a program that can "read" JavaScript code and accurately give the results of its execution.
For example, when you write var a = 1 + 1; what the JavaScript engine does is understand (parse) your code and change the value of a to 2.
People who have learned the principles of compilation know that for static languages (such as Java, C++, C), the one that handles these things is called Compiler, and accordingly for dynamic languages such as JavaScript, it is called Interpreter. The difference between the two can be summed up in one sentence: the compiler compiles the source code into another type of code (such as machine code, or bytecode), while the interpreter parses the code directly and outputs the results of the code. For example, firebug's console is a JavaScript interpreter.
However, it is difficult to define whether the JavaScript engine is an interpreter or a compiler, because, for example, V8 (Chrome's JS engine), in order to improve the performance of JS, it compiles JS to native machine code (native machine code) before running, and then executes the machine code (which is much faster).
What is the relationship between JavaScript parsing engine and ECMAScript
The JavaScript engine is a program, and the JavaScript code we write is also a program. How to make the program understand the program? This requires the definition of rules. For example, var a = 1 + 1, which is mentioned earlier, says:
Var on the left represents this is the declaration, which declares the variable a.
The + on the right means to add 1 and 1.
The equal sign in the middle indicates that this is an assignment statement.
The last semicolon indicates that the sentence is over.
These are the rules, and with it there is a standard by which the JavaScript engine can parse JavaScript code. So the ECMAScript here defines these rules. The document ECMAScript 262 defines a complete set of standards for the language JavaScript. These include:
Var,if,else,break,continue is the key word of JavaScript.
Abstract,int,long and so on are reserved words of JavaScript.
How is it a number, how is it a string, etc.
Defines the operators (+, -, >, load)
Whether css loading blocks dom tree rendering
What we're talking about here is the introduction of css into the head.
First of all, we all know that css is downloaded asynchronously by a separate download thread.
Then let's talk about a few phenomena:
Css loading does not block DOM tree parsing (DOM builds as usual during asynchronous loading)
However, it blocks the rendering of the render tree (you have to wait for the css to load, because the render tree requires css information)
This may also be an optimization mechanism for browsers. Because you may change the style of the following DOM node when you load css, if the css load does not block the rendering of the render tree, then when the css is loaded, the render tree may have to be redrawn or reflowed, which causes some unnecessary wear and tear.
So simply parse the structure of the DOM tree first, finish the work that can be done, and then wait for you to load the css, and then render the render tree according to the final style, which will indeed have better performance.
Normal layer and compound layer
The concept of composite is mentioned in the rendering step.
It can be simply understood that the layers rendered by browsers generally contain two main categories: normal layers and composite layers.
First of all, the ordinary document stream can be understood as a composite layer (here it is called the default composite layer, no matter how many elements are added, it is actually in the same composite layer)
Second, the absolute layout (as does fixed), although it can be separated from the normal document stream, it still belongs to the default composite layer.
Then, you can declare a new composite layer through hardware acceleration, which allocates resources separately (of course, it also deviates from the normal document flow, so that no matter how the composite layer changes, it does not affect the backflow redrawing in the default composite layer).
It can be understood simply: in GPU, each composite layer is drawn separately, so it does not affect each other, which is why the hardware acceleration effect of some scenes is excellent.
As you can see in Chrome DevTools-> More Tools-- > Rendering-- > Layer borders, the yellow one is the composite layer information.
How to become a composite layer (hardware acceleration)
Turning this element into a composite layer is the legendary hardware acceleration technology.
The most commonly used methods: translate3d, translateZ
Opacity attribute / transition animation (composite layers are created only during the execution of the animation, and the elements return to their previous state after the animation does not start or end)
The will-chang attribute (this is rather remote) is generally used with opacity and translate to inform the browser in advance of the change, so that the browser will start to do some optimization work (this is best released after use)
Video, iframe, canvas, webgl and other elements
Others, such as the previous flash plug-in
The difference between absolute and hardware acceleration
As you can see, although absolute can break away from the normal document stream, it cannot break away from the default composite layer. Therefore, even if the information in absolute does not change the render tree in the ordinary document stream, when the browser finally draws, it is the whole composite layer, so the change of information in absolute will still affect the rendering of the whole composite layer. (the browser will redraw it. If there is a lot of content in the composite layer, the rendering information brought by absolute changes too much, and the resource consumption is very serious.)
The hardware acceleration is directly in another composite layer (starting a new stove), so its information change will not affect the default composite layer (of course, the interior will certainly affect its own composite layer), just trigger the final composition (output view)
The role of composite layers
In general, an element will become a composite layer when hardware acceleration is enabled, which can be independent of the ordinary document stream. After modification, the whole page can be avoided and the performance can be improved. But try not to use a large number of composite layers, otherwise, due to excessive consumption of resources, the page will become more stuck.
Use index for hardware acceleration
When using hardware acceleration, use index as much as possible to prevent browsers from creating composite layer renderings for subsequent elements by default
The specific principle goes like this: in webkit CSS3, if hardware acceleration is added to this element and the index level is relatively low, then other elements behind this element (with a higher level than this element, or the same level, and the same releative or absolute attributes) will become composite layer rendering by default, which will greatly affect performance if not handled properly
To put it simply, it can be thought of as an implicit composite concept: if an is a composite layer and b is on top of a, then b will also be implicitly converted to a composite layer, which requires special attention.
On the Operation Mechanism of JS from EventLoop
At this point, it is something that belongs to the browser page after the first rendering, and some analysis of the running mechanism of the JS engine.
Note that instead of talking about executable context, VO,scop chain, and other concepts (which can be sorted out into another article), this is mainly about how JS code is executed in conjunction with Event Loop.
The premise for reading this section is that you already know that the JS engine is single-threaded, and you will use several of the concepts mentioned above:
JS engine thread
Event trigger thread
Timing trigger thread
Then understand a concept:
JS is divided into synchronous tasks and asynchronous tasks.
Synchronization tasks are executed on the main thread, forming an execution stack
In addition to the main thread, the event trigger thread manages a task queue and places an event in the task queue as long as the asynchronous task has a run result.
Once all the synchronous tasks in the execution stack are executed (when the JS engine is idle), the system reads the task queue, adds runnable asynchronous tasks to the executable stack, and starts execution.
Look at the picture:
When you see this, you should be able to understand why sometimes events pushed by setTimeout can't be executed on time. Because it is possible that when it is pushed into the event list, the main thread is not idle and is executing other code, there is a natural error.
The event cycle mechanism is further supplemented.
The picture above is roughly described as follows:
When the main thread runs, the execution stack is generated. When the code in the stack calls some api, they will add various events to the event queue (when the trigger condition is met, such as the ajax request is completed).
And when the code in the stack is executed, it reads the events in the event queue to execute those callbacks, and so on.
Note that you always have to wait for the code in the stack to finish executing before reading the events in the event queue
Let's talk about the timer separately.
The core of the above event loop mechanism is: JS engine thread and event trigger thread
But there are some hidden details in the event, such as how do you wait a specific time before adding to the event queue after calling setTimeout?
Is it detected by the JS engine? Of course not. It is controlled by timer threads (because the JS engine is too busy to split up at all)
Why separate timer threads? Because the JavaScript engine is single-threaded, the accuracy of timing will be affected if it is in a blocked thread state, so it is necessary to open a separate thread for timing.
When will timer threads be used? When using setTimeout or setInterval, it requires timer thread timing, and when the timing is complete, specific events are pushed into the event queue.
SetTimeout instead of setInterval
There is a difference between simulating periodic timing with setTimeout and directly using setInterval.
Because each time the setTimeout timing arrives, it will be executed, and then the setTimeout will continue after a period of execution, with more errors in the middle (the error is more or less related to the code execution time)
On the other hand, setInterval pushes an event at precise intervals every time, but the actual execution time of the event may not be accurate, and it is possible that the next event will come before the execution of this event is finished.
And some of the fatal problems with setInterval are:
Cumulative effect, if the setInterval code is not finished before it is added to the queue again, it will cause the timer code to run several times in a row without interval. Even at normal intervals, code execution time for multiple setInterval may be less than expected (because code execution takes a certain amount of time)
For example, browsers such as iOS's webview or Safari all have a feature that JS is not executed when scrolling. If you use setInterval, you will find that the accumulated callback will be executed many times after scrolling because JS is not executed. If the callback execution time is too long, it will cause stutter problems and some unknown errors. (this piece is supplemented later. The optimization that comes with setInterval will not add callbacks repeatedly.)
And when minimizing the display of the browser and other operations, setInterval does not not execute the program, it will put the callback function of setInterval in the queue, and when the browser window opens again, all of it will be executed in an instant
Therefore, in view of so many problems, it is generally believed that the best solution is to use setTimeout to simulate setInterval, or to use requestAnimationFrame directly for special occasions.
Add: it is mentioned in JS elevation that the JS engine will optimize setInterval. If there is a callback of setInterval in the current event queue, it will not be added repeatedly.
Event cycle advance: macrotask and microtask
After combing through the JS event loop mechanism above, it is sufficient in the case of ES5, but in the current era of ES6, we will still encounter some problems, such as the following question:
Console.log ('script start'); setTimeout (function () {console.log (' setTimeout');}, 0); Promise.resolve () .then (function () {console.log ('promise1');}) .then (function () {console.log (' promise2');}); console.log ('script end')
Mm-hmm, the correct order of execution is as follows:
Script startscript endpromise1promise2setTimeout
Why? Because there's a new concept in Promise: microtask.
Or, further, there are two types of tasks in JS: macrotask and microtask, and in ECMAScript, microtask is called jobs,macrotask or task.
What are their definitions? The difference? To keep it simple, it can be understood as follows:
1. Macrotask (also known as macro task)
It can be understood that each execution of code executed by the stack is a macro task (including getting an event callback from the event queue and putting it on the execution stack for execution)
Each task will complete this task from beginning to end, and will not perform anything else.
In order to enable JS internal task and DOM tasks to be executed in an orderly manner, the browser renders the page (task-> render-> task->) after one task execution ends and before the next task execution begins. )
2. Microtask (also known as microtask)
Understandably, it is a task that is executed immediately after the end of the current task execution
That is, after the current task session, before the next task, before rendering
So it responds faster than setTimeout (setTimeout is task) because you don't have to wait for rendering.
That is, after a macrotask is executed, all microtask generated during its execution will be executed (before rendering)
3. What kind of scenes will form macrotask and microtask?
Macrotask: main code block, setTimeout,setInterval, etc. (each event in the event queue is a macrotask)
Microtask:Promise,process.nextTick et al.
Add: in node environment, process.nextTick takes priority over Promise, which can be simply understood as: after the macro task ends, the nextTickQueue part of the micro task queue will be executed first, and then the Promise part of the micro task will be executed.
Let's understand it according to the thread:
(1) all events in macrotask are placed in an event queue, which is maintained by the event trigger thread.
(2) all micro tasks in microtask are added to the micro task queue (Job Queues), waiting for the current macrotask to be executed, which is maintained by the JS engine thread (this is understood by oneself + inferred, because it is executed seamlessly under the main thread)
So, summarize the operating mechanism:
Perform a macro task (get it from the event queue if it is not in the stack)
If you encounter a micro-task during execution, add it to the task queue of the micro-task
After the macro task is executed, all the micro tasks in the current micro task queue are executed immediately (in turn)
After the execution of the current macro task, check the rendering, and then the GUI thread takes over the rendering
After rendering, the JS thread continues to take over and start the next macro task (get from the event queue)
As shown in the figure:
In addition, note the difference between the polyfill of Promise and the official version:
In the official version, it is the standard microtask form.
Polyfill is generally simulated through setTimeout, so it is in the form of macrotask
Note that some browsers have different execution results (because they may execute microtask as macrotask), but for simplicity, some scenarios under nonstandard browsers are not described here (but remember, some browsers may not be standard)
Supplement: using MutationObserver to implement microtask
MutationObserver can be used to implement microtask (it belongs to microtask and has a priority less than Promise, which is usually done when Promise does not support it)
It is a new feature in HTML5 to listen for a DOM change, and Mutation Observer will be notified of any changes to the DOM object tree
Like the previous Vue source code, it is used to simulate nextTick. The specific principle is to create a TextNode and listen for changes in the content, and then modify the text content of this node when you want to nextTick, as follows:
Var counter = 1var observer = new MutationObserver (nextTickHandler) var textNode = document.createTextNode (String (counter)) observer.observe (textNode, {characterData: true}) timerFunc = () = > {counter = (counter + 1) 2 textNode.data = String (counter)}
However, the current nextTick implementation of Vue (2.5 +) removes the MutationObserver approach (allegedly for compatibility reasons) and replaces it with MessageChannel (of course, the default is still Promise, which is only compatible if it is not supported).
MessageChannel belongs to the macro task, and the priority is: MessageChannel- > setTimeout, so the nextTick inside Vue (2.5 +) is different from the previous implementation, which requires attention.
At this point, the study of "what is the operating mechanism and principle of JavaScript" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.