Home  >  Article  >  Web Front-end  >  How to optimize JavaScript script performance_javascript tips

How to optimize JavaScript script performance_javascript tips

WBOY
WBOYOriginal
2016-05-16 19:19:47927browse

From:http://www.nirvanastudio.org/javascript/improve-javascript-performance.html

Author: ShiningRay @ Nirvana Studio

With the development of the network, network speed and machine speed With the improvement of technology, more and more websites use rich client technology. Now Ajax is the most popular method. JavaScript is an interpreted language, so whether it can reach the same level as C/Java limits what it can do on the client. In order to improve its performance, I want to build on what I have done for JavaScript before. Many tests to talk about my own experience, hoping to help everyone improve their JavaScript script performance.

In terms of language level
Loop
Loop is a very commonly used control structure. Most things rely on it to complete. In JavaScript, we can use for(; ;), while(), and for(in) three types of loops. In fact, among these three loops, for(in) is extremely inefficient because it needs to query the hash key. It should be used as little as possible if possible. The performance of for(;;) and while loop should be said to be basically equivalent (when used in daily use).

In fact, how to use these two loops is very particular. I had some interesting situations in my testing, see the appendix. The final conclusion is:

If the loop variable is incrementing or decrementing, do not assign a value to the loop variable separately. You should use the nested or - operator when it is read for the last time.

If you want to compare with the length of the array, you should put the length attribute of the array into a local variable in advance to reduce the number of queries.

Local variables and global variables
Local variables are accessed faster than global variables, because global variables are actually members of the global object, while local variables are placed in in the stack of functions.

Not using Eval
Using eval is equivalent to calling the interpretation engine again to run the content at runtime, which takes a lot of time. At this time, function templates can be implemented using closures supported by JavaScript (for details on closures, please refer to the relevant content of functional programming)

Reduce object search
Because of JavaScript’s interpretation property, so a.b.c.d.e needs to perform at least 4 query operations, first check a, then check b in a, then check c in b, and so on. Therefore, if such expressions appear repeatedly, such expressions should be kept as rare as possible as much as possible. You can use local variables to put them in a temporary place for querying.

This can be combined with looping, because we often need to loop based on the length of strings and arrays, and usually this length is unchanged. For example, every time we query a.length, we need to perform an additional operation, and setting var len=a.length in advance will save one query.

String connection
If you are appending a string, it is best to use the s =anotherStr operation instead of using s=s anotherStr.

If you want to connect multiple strings, you should use = less, such as

s =a;s =b;s =c; it should be written as

s =a b c; if you are collecting strings, such as performing = operations on the same string multiple times, it is best to use a cache. How to use it? Use JavaScript arrays to collect, and finally use the join method to connect, as follows

var buf = new Array();for(var i = 0; i < 100; i ){ buf.push(i.toString ());}var all = buf.join("");Type conversion
Type conversion is a common mistake that everyone makes, because JavaScript is a dynamically typed language and you cannot specify the type of the variable.

1. Convert numbers into strings and use "" 1. Although it looks a bit ugly, in fact this is the most efficient, in terms of performance:

("" ) > String() > .toString() > new String()

This is actually somewhat similar to the "direct quantity" below. Try to use internal operations that can be used at compile time rather than at run time. The user operations used should be fast.

String() is an internal function, so it is very fast, while .toString() needs to query the function in the prototype, so it is not as fast. new String() is used to return an exact copy.

2. Converting floating point numbers to integers is more error-prone. Many people like to use parseInt(). In fact, parseInt() is used to convert strings into numbers, not between floating point numbers and integers. To convert between, we should use Math.floor() or Math.round().

In addition, unlike the problem in object search in Section 2, Math is an internal object, so Math.floor() actually does not take much query method and calling time, and is the fastest.

3. For custom objects, if the toString() method is defined for type conversion, it is recommended to explicitly call toString(), because the internal operation will try the object after trying all possibilities. The toString() method tries to see if it can be converted into String, so calling this method directly will be more efficient

Use a direct quantity
In fact, this impact is relatively small and can be ignored.What does it mean to use direct quantities? For example, JavaScript supports using [param, param, param,...] to directly express an array. In the past, we all used new Array(param, param,...). Using the former is directly interpreted by the engine. , the latter requires calling an Array internal constructor, so it is slightly faster.

Similarly, the method of var foo = {} is faster than var foo = new Object();, and var reg = /../; is faster than var reg=new RegExp().

String traversal operation
For loop operations on strings, such as replacement and search, regular expressions should be used, because the loop speed of JavaScript itself is relatively slow, and regular expressions The operation is a language API written in C, and the performance is very good.

Advanced Objects
Custom advanced objects and Date and RegExp objects consume a lot of time in construction. If it can be reused, caching should be used.

DOM related
Insert HTML
Many people like to use document.write in JavaScript to generate content for the page. In fact, this is less efficient. If you need to insert HTML directly, you can find a container element, such as specifying a div or span, and set their innerHTML to insert your own HTML code into the page.

Object query
Using [""] query is faster than .items(). This is the same as the previous idea of ​​reducing object search, calling .items() Added a query and function call.

Create DOM nodes
Usually we may use strings to write HTML directly to create nodes. In fact, doing so

cannot guarantee the validity of the code

String operation efficiency is low

So the document.createElement() method should be used, and if there are ready-made template nodes in the document, the cloneNode() method should be used, because After using the createElement() method, you need to set the attributes of the element multiple times. Using cloneNode() can reduce the number of attribute settings - similarly, if you need to create many elements, you should prepare a template node first.

Timer
If you are targeting code that is constantly running, setTimeout should not be used, but setInterval should be used. setTimeout resets a timer each time.

Others
Script engines
According to my test, the efficiency of Microsoft's JScript is much worse than Mozilla's Spidermonkey, both in terms of execution speed and memory management, because JScript is now basically It is not updated either. But SpiderMonkey cannot use ActiveXObject

File optimization
File optimization is also a very effective method. Delete all spaces and comments and put the code in one line to speed up the download. , note that it is the download speed rather than the parsing speed. If it is local, comments and spaces will not affect the interpretation and execution speed.

Summary
This article summarizes some of the methods I have found in JavaScript programming to improve JavaScript running performance. In fact, these experiences are based on several principles:

It is faster to directly use what is readily available. For example, local variables are faster than global variables, direct variables are faster than constructing objects at runtime, etc.

Reduce the number of executions as much as possible, such as caching those that require multiple queries first.

Use built-in language features as much as possible, such as string links.

Use the APIs provided by the system as much as possible, because these APIs are compiled binary codes and have high execution efficiency

At the same time, some basic algorithm optimizations can also be used in JavaScript , such as the adjustment of the operation structure, will not be described in detail here. However, since JavaScript is interpreted, bytecodes are generally not optimized at runtime, so these optimizations are still very important.

Of course, some of the techniques here are also used in other interpreted languages, and you can also refer to them.

Reference
http://www.umsu.de/jsperf/ Test comparison of various browsers

http://home.earthlink.net/~kendrasg/info/ js_opt/

Appendix 1
Since it was a test done before, the test code is incomplete. I have added a part as follows:

Copy the code The code is as follows:

var print;

if(typeof document != "undefined" ){
print = function(){
document.write(arguments[0]);
}
}else if(typeof WScript != "undefined" ){
print = function(){
WScript.Echo(arguments[0],arguments[1],arguments[2]);
}
}

function empty(){
}

function benchmark(f){
var i = 0;
var start = (new Date()).getTime();

while(i < pressure){
f(i );
}
var end = (new Date()).getTime();
WScript.Echo(end-start);
}

/*
i=0
start = (new Date()).getTime();
while(i < 60000){
c = [i,i,i,i,i,i,i,i,i,i];
i ;
}
end = (new Date()).getTime();
WScript.Echo(end-start);
i=0
start = (new Date()).getTime();
while(i < 60000){
c = new Array(i,i,i,i,i,i,i,i,i,i);
i ;
}
var end = (new Date()).getTime();
WScript.Echo(end-start);
*/

function internCast(i){
return "" i;
}

function StringCast(i){
return String(i)
}
function newStringCast(i){
return new String(i)
}
function toStringCast(i){
return i.toString();
}
function ParseInt(){
return parseInt(j);
}
function MathFloor(){
return Math.floor(j);
}
function Floor(){
return floor(j);
}
var pressure = 50000;
var a = "";
var floor = Math.floor;
j = 123.123;
print("-------------nString Conversion Test");
print("The empty:", benchmark(empty));
print("intern:", benchmark(internCast));
print("String:");
benchmark(StringCast);
print("new String:");
benchmark(newStringCast);
print("toString:");
benchmark(toStringCast);
print("-------------nFloat to Int Conversion Test");
print("parseInt");
benchmark(ParseInt);
print("Math.floor");
benchmark(MathFloor);
print("floor")
benchmark(Floor);

function newObject(){
return new Object();
}

function internObject(){
return {};
}
print("------------nliteral Test");
print("runtime new object", benchmark(newObject));
print("literal object", benchmark(internObject));

附录2
代码1:
复制代码 代码如下:

for(var i=0;i<100;i ){
arr[i]=0;
}

代码2:
复制代码 代码如下:

var i = 0;
while(i < 100){
arr[i ]=0;
}

代码3:

复制代码 代码如下:

var i = 0;
while(i < 100){
arr[i]=0;
i ;
}

在firefox下测试这两段代码,结果是代码2优于代码1和3,而代码1一般优于代码3,有时会被代码3超过;而在IE 6.0下,测试压力较大的时候(如测试10000次以上)代码2和3则有时候优于代码1,有时候就会远远落后代码1,而在测试压力较小(如5000次),则代码2>代码3>代码1。

代码4:

复制代码 代码如下:

var i = 0;
var a;
while(i < 100){
a = 0;
i ;
}


代码5:

复制代码 代码如下:

var a;
for(var i=0;i<100;i ){
a = 0;
}
上面两段代码在Firefox和IE下测试结果都是性能接近的。

代码6:

复制代码 代码如下:

var a;
var i=0;
while(i<100){
a=i;
i ;
}

代码7:

复制代码 代码如下:

var a;
var i=0;
while(i<100){
a=i ;
}


Code 8:

Copy code The code is as follows:

var a;
for(var i=0;i<100;i ){
a = i;
}

Code 9:

Copy code The code is as follows:

var a;
for(var i=0;i<100 ;){
a = i ;
}

The performance of these four pieces of code under Firefox 6 and 8 is close, the performance of 7 and 9 is close, and 6, 8 < 7, 9;

Finally let’s take a look at the empty loop

Code 10:

for(var i=0;i<100;i ){ }


Code 11:

var i;
while(i<100){ i Time spent with code 11 is approximately 24:1. Therefore, it does not have reference value, so I did not show it to everyone at the beginning.
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:Code: loadScript() function to load js_javascript skillsNext article:Code: loadScript() function to load js_javascript skills

Related articles

See more