In the browser, JavaScript Execution and UI update occur in the same process (Browser UI thread. The work of the UI thread is based on a simple queue system. tasks are saved to the queue until they are extracted and executed when the process is idle. Therefore, JavaScript Execution will block UI updates. Conversely, UI updates will also block JavaScript Execution. This means that the browser does not respond for a short or long time at work, and users' operations cannot be responded to in a timely manner. The blocking of the UI thread is often causedCodeThe browser's response is lost and the user interface is frozen.
Therefore, we have to consider the problem of UI threads for time-consuming operations during encoding. High Performance JavaScript recommends that the time-consuming JavaScript operations should not exceed 100 milliseconds, how can we get this 100 ms?
Let's take a look at two related studies:
1.1. Definitions of response time
Reference: Robert B. MILLER: response time in man-computer conversational
Different types of responses and response latencies apply to different behavior levels. The response time is defined based on the estimation of the psychological basis. In his study, Robert Miller defined 17 different types of response times. Interested people can read them carefully. Here we only list two important items:
Topic 1. Response to control activation (switch control response)
The click of the typewriter key, or the change in control force after moving a switch past a detent position are examples. they indicate responsiveness of the terminal as an object. this response shoshould be immediate and perceived as a part of the mechanical action induced by the operator. time delay: no more than 0.1 second.
In switch operations, the corresponding terminal capabilities should be direct and perceptible to the operator. This type of latency should not be greater than 0.1 seconds.
The delay between depressing the key and the visual feedback shocould be no more than 0.1 to 0.2 seconds.
The latency between buttons and visual feedback should not be greater than 0.1 ~ 0.2 seconds.
Note that this delay in feedback may be far too slow for skilled keyboard users.
The study also mentioned that the above values are still very slow for those keyboard masters. Their expected value is higher than the average person, so the above value is only a common value.
Topic 13. Graphic response from light pen (cursor graphic response)
Where the lines are drawn with deliberation by the user-relatively slowly as compared with slashing sketch strokes-a delay of up to 0.1 second seems to be acceptable. there must not be variability perceived by the user in this delay.
The user's cursor input delay, 0.1 seconds is acceptable. Users can dynamically perceive the delay period.
The response delay in the image following the light pen may be as much as one second because the user is not tracing a line but positioning an image that, for him, is completed when his stylus touches the destination for the image.
In the diagram, a similar latency of 1 second is acceptable.
1.2. response times: The 3 important limits
Reference: Jakob Nielsen: response times: The 3 important limits
0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary failed t to display the result.
1.0 second is about the limit for the user's flow of thought to stay uninterrupted, even though the user will notice the delay. normally, no special feedback is necessary during delays of more than 0.1 but less than 1.0 second, but the user does lose the feeling of operating directly on the data.
10 seconds is about the limit for keeping the user's attention focused on the dialogue. for longer delays, users will want to perform other tasks while waiting for the computer to finish, so they shoshould be given feedback indicating when the computer expects to be done. feedback during the delay is especially important if the response time is likely to be highly variable, since users will then not know what to expect CT.
Response time: three important limits
0.1 senond: 0.1 s, limited to user-aware system instantaneous response, meaning no special feedback is required.
1.0 senond: 1.0 s, the limit is that the user's thinking is not interrupted, even if the user feels the delay. Generally ~ No special feedback is needed between 1.0s, but the user does feel the loss of interest in this operation.
10 seconds: 10 s, the limit is the user's attention limit in the conversation; a longer delay will cause the user to switch to another task to wait for the computer to complete the current task. Therefore, a proper feedback is required before the computer completes the current task. If the response time is highly variable, feedback during the delay is especially important because the user does not know what will happen next.
In actual work, many tasks cannot be completed within Ms. Many complex operations (such as recursion and iteration) occupy the UI thread. Other operations of the user are not responded in a timely manner, and browser interfaces are frozen and stack overflow often occur. Most browsers will prompt the user whether to terminate the operation in case of a long script operation. For many users, the termination operation is definitely the majority.
2. Call Stack size limit:
ComplexAlgorithmRecursion is usually used. For example, if the Fibonacci sequence is used, the execution of the recursive function is limited by the call stack limits of the browser ).
What is the call stack restriction? The explanation in High Performance Javascript is as follows:
The amount of recursion supported by Javascript Engines varies and is directly related to the size of the Javascript call stack. with the exception of Internet Explorer, for which the call stack is related to available system memory, all other browsers have static call stack limits. the call stack size for the most recent browser versions is relatively high compared to older browsers (Safari 2, for instance, had a call stack size of 100 ).
The number of recursion supported by the JavaScript engine is directly related to the call stack size. Except for IE, its call stack size is related to the system memory. other browsers have fixed call stack size restrictions. The call stack size of most modern browsers is higher than that of older browsers (for example, safari2, the call stack size is 100 ).
Figure 4-2. Javascript call stack size in browsers (Figure 4-2. browser call stack size)
You can perform a simple test on the browser's call stack depth:
VaR I = 0;
Function FN (){
FN (I ++ );
}
Try {
FN ();
} Catch (e ){
Alert (I );
}
Test results ):
Firefox 6.0 9015
Chrome 14
26176
Opera 11.51 32631
IE7/8 3064
IE6 1131
From the data point of view, recursion is not unlimited, and the calling stacks of different browsers vary greatly. During the recursive call process, the system will open up a stack for each layer of return points for storage. First, it expands step by step, and then it shrinks backtracing. With the increase in the number of recursion times, the resources consumed will also increase, stack Overflow may eventually occur. Therefore, when using recursion, you must have a clear recursion termination condition, also called recursion exit.
For repeated operations, you can use the memoization technology to cache the previous operation results to reduce the performance loss caused by repeated operations. Memoization mainly uses a hash (or key-Value Pair) to cache computation results. It is faster to query tables than to execute functions to achieve performance optimization.
The following is a simple implementation of the Fibonacci sequence:
Function Fibonacci (n ){
N = parseint (n, 10 );
If (n <2 ){
Return N;
}
Return maid (n-1) + maid (n-2 );
}
(The following data is tested based on IE8)
Number of function calls (times) elapsed time (MS)
Fibonacci (10) 77 0
Fibonacci (20) 1891 16
Fibonacci (30) 2692537 2344
With the increase of N, the number of calls and time consumption increase significantly. If you discard the time consumed, you will find that the browser is no longer able to respond to user operations, and the browser UI thread is blocked. During the execution of Fibonacci (40), the prompt "whether to stop running this script" appears continuously in IE.
After using the memoization technology, the implementation version is as follows:
VaR maid = (function (){
VaR cache = [1, 1];
VaR fib = function (n ){
If (n> 1 ){
For (VAR I = cache. length; I <= N; I ++ ){
Cache [I] = cache [I-1] + cache [I-2];
}
}
Return cache [n-1];
};
Return fib;
})();
Iterations replace recursion, without the browser call stack size limit, and the performance improvement is very obvious. If you are interested in Tx, you can compare them by yourself. The efficiency is no longer an order of magnitude.
3. long-running script restrictions
Or the above use of the memoization technology to implement the Fibonacci function, the execution of the Fibonacci (10000000), due to the long operation time, triggering the browser to run the script for a long time, the UI thread is blocked. Therefore, there are large-scale operations in the iteration, and tasks that cannot be completed within ms can be split, so that JavaScript temporarily gives the UI thread control permission to execute other tasks.
To temporarily control the UI thread, you can use setTimeout.
Time Precision of setTimeout:
In JavaScript, the timer has a time precision. In ie9 (non-Charging mode), IE8 and earlier versions, the time precision is 15.6 ms; In ie9 (Charging mode), the time precision is 4 ms; other browsers are generally 4 ms, which will reduce the battery life. Therefore, setTimeout (FN, 0) is not executed immediately. The execution time depends on the time precision.
To solve the time precision problem of setTimeout in different browsers, W3C introduces a new setimmediate () function. Setimmediate is similar to setTimeout. setimmediate inserts tasks into the queue and executes tasks when the UI thread is idle. We do not need to care about the impact of time precision. In addition, setimmediate is executed faster than setTimeout (FN, 0.
Due to the uncertainty of the task running time, you can add computing time monitoring in the iteration operation to determine whether the task needs to be split in this iteration.
Let's make a simple demo, 0 ~ N accumulation operation:
// O ~ N accumulation operation
VaR test = function (n, callback ){
VaR result = 0;
VaR I = 0;
(Function (){
VaR ST = + new date ();
For (; I <n; I ++ ){
If (+ new date ()-ST <100 ){
Result ++;
} Else {
SetTimeout (arguments. callee, 0); // when the calculation time difference is greater than ms, the operation is interrupted, giving control of the UI thread
Return;
}
}
Callback & callback ();
})();
};
Test (10000000, showresult); // Accumulate 10 million times
Due to the additional process control overhead, the setTimeout method consumes more time than the direct operation. The advantage is that the UI thread is no longer congested and can process more tasks.
In addition to the setTimeout method, it is also a solution to put operations that require long-time operations into flash to avoid the impact of a single JavaScript thread.
Duff's device (Duff device ):
Duff's device is a kind of loop acceleration technique. Its idea is to minimize the number of loop executions.
/**
* Duff's device
* Http://home.earthlink.net /~ Kendrasg/INFO/js_opt/jsoptmain.html # Du sdevice
*/
VaR n = iterations/8;
VaR casetest = iterations % 8;
Do {
Switch (casetest ){
Case 0:
Testval ++;
Case 7:
Testval ++;
Case 6:
Testval ++;
Case 5:
Testval ++;
Case 4:
Testval ++;
Case 3:
Testval ++;
Case 2:
Testval ++;
Case 1:
Testval ++;
}
Casetest = 0;
} While (-- N> 0 );
The above is an implementation version of Duff's device.
Duff's device divides a large loop into eight small loops in each iteration, and executes a small loop in the remainder of 8 to reduce the number of loops.
HTML5 web workers:
With the development of HTML5 technology, it is possible to run JavaScript code outside the browser UI thread. Web workers provides a simple way for JavaScript code to run in the background thread without affecting the UI thread. Each web workers is independent of each other and runs in its own thread.
var worker = new worker ('My _ task. js');
worker. onmessage = function (event) {// This event handler will be called when the worker callits own postmessage () function
console. log ("called back by the worker! \ N ");
};
worker. postmessage (); // start the worker
worker. terminate (); // terminate a running worker
note that Dom cannot be manipulated in Web workers and can be used to process long-running scripts unrelated to the UI thread. Java-JavaScript