This is the second article by Nicholas discussing how to prevent scripts from getting out of control. It mainly discusses how to refactor nested loops, recursion, and functions that execute many sub-operations within the function at the same time. Basic Ideas
This is the same as the trunk () example in the previous section. If several operations have no specific execution sequence and are not dependent on each other, we can execute them through asynchronous calls, not only to reduce execution
The number of rows to prevent the script from getting out of control. This article also introduces how to replace recursion with memoization.
[Original article title] speed up your JavaScript, part 2
[Author] Nicolas C. zakas
The following is a translation of the original text:
Last week, I wrote
(Translated: how to speed up JavaScript (Circular)
) This article introduces the first reason why JavaScript runs too long. Similar situations sometimes occur in the definition of functions, and functions may be overloaded due to improper use. Generally, a function contains too many loops (not too much content in the loop), too many recursion, or too many irrelevant operations that need to be executed together.
Too
Multiple loops are usually nested. This type of code keeps occupying the JavaScript engine until the loop ends. There is a very famous example in this regard, that is, using the bubble Algorithm for sorting. Because
Javascript has a built-in sort () method. We do not need to use this method for sorting, but we can use this algorithm to understand the crux of the resource occupation by nested loops, so as to avoid class
Similar to the situation. The following is a typical example of using the Bubble sorting method in javascript:
function bubbleSort(items) {for (var i = items.length - 1; i >= 0; i--) { for (var j = i; j >= 0; j--) { if (items[j] < items[j - 1]) { var temp = items[j]; items[j] = items[j - 1]; items[j - 1] = temp; } }}}
Recall the computer knowledge you learned at school. You may remember that the Bubble sorting method is one of the most efficient sorting algorithms, because for an array containing n elements, N is required for square cycles.
. If the number of elements in the array is very large, this operation will take a long time. The internal loop operation is very simple. It is only responsible for comparing and exchanging values. The biggest cause of the problem is the number of cycles. This will
The browser runs abnormally. The potential direct result is the warning dialog box for the script to get out of control.
A few years ago, Yahoo researcher Julien Lecomte wrote an article entitled "Running CPU intensive JavaScript computations in a web browser
In this article, the author explains how to break down a large JavaScript operation into several small parts. In one example, the Bubble sorting method is divided into multiple steps, and each step only traverses the array once. I have improved his code, but the methods are the same:
function bubbleSort(array, onComplete) {var pos = 0; (function() { var j, value; for (j = array.length; j > pos; j--) { if (array[j] < array[j - 1]) { value = data[j]; data[j] = data[j - 1]; data[j - 1] = value; } } pos++; if (pos < array.length) { setTimeout(arguments.callee, 10); } else { onComplete(); }})();}
This function uses an asynchronous manager to implement the bubble algorithm. It is paused before each array traversal. The oncomplete () function is triggered after the array is sorted, prompting that user data has been prepared.
Okay. The bubblesort () function uses the same basic technology as the chunk () function (refer to my previous post) to encapsulate the behavior in an anonymous function
Arguments. callee is passed to setTimeout () for repeated operations until the sorting is complete. If you want to split the nested loop into several small steps to achieve
This function provides good guidance for the purpose of emancipating the browser.
Similar problems include excessive recursion. Each additional recursive call consumes more memory, which slows down the running of the browser. What's annoying is that you may exhaust the system memory before the browser sends a warning of the script being out of control, causing the browser to stop responding. Crockford once asked this question on his blog.
In-depth discussion. He used the example to recursively generate a Fibonacci series.
function fibonacci(n) {return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2);};
According to crockford, executing the Fibonacci (40) Statement will call itself 331160280 times repeatedly. One solution to avoid recursion is to use memoization.
Technology, which can obtain the execution result of the last call. Crockford introduced the following function, which can be added to the function for processing values:
function memoizer(memo, fundamental) {var shell = function (n) { var result = memo[n]; if (typeof result !== 'number') { result = fundamental(shell, n); memo[n] = result; } return result;};return shell;};
He then applies this function to the Fibonacci series generator:
var fibonacci = memoizer([0, 1],function(recur, n) { return recur(n - 1) + recur(n - 2);});
At this time, if we call Fibonacci (40) again, we will only call it 40 times, which is much improved compared with the original one. The principle of memoization can be summarized as a single sentence. In the same result, you do not have to calculate twice. If a result is used again, save the result to make it faster than the new one.
The last reason that may slow the function execution is that we have mentioned that the function executes too much content, usually because it uses a development mode similar to the following:
function doAlot() { doSomething(); doSomethingElse(); doOneMoreThing();}
Here we need to execute three different functions. Please note that no matter which function is used, other functions are independent in the execution process. They are relatively independent in nature, it only needs to be executed one by one at a specific time. Similarly, you can use a method similar to chunk () to execute a series of functions without locking the browser.
function schedule(functions, context) {setTimeout(function() { var process = functions.shift(); process.call(context); if (functions.length > 0) { setTimeout(arguments.callee, 100); }},100);}
The schedule function has two parameters: one is the array containing the function to be executed, and the other is the context object that indicates the context of this. The Function Array is implemented in queue mode. When a timer event is triggered, the function at the top of the queue is taken and executed. This function can execute a series of functions in the following way:
schedule([doSomething, doSomethingElse, doOneMoreThing], window);
We hope that process processing functions like this will be added to various JavaScript class libraries. In Yui 3.0, queue has been introduced.
Object. You can use timer to call a group of functions consecutively.
None
The degree to which existing technologies can help us split complex processes is very important for developers to use this method to understand and determine the bottleneck of out-of-control scripts. Whether it's too many loops, recursion, or
What is other, you should know now if you are dealing with similar situations. However, remember that the technologies and functions mentioned here only serve as a reference. In actual applications, you should improve them.
In order to play a greater role.