Javascript Advanced Programming

Source: Internet
Author: User
Tags windows shell script

Download time

The Web browser downloads the JavaScript source code, that is, all the long variables and comments will be included. This and other factors increase the download time, which increases the total time of script running. The key factor to increase the download time is the number of bytes contained in the script.

Remember that a key number is 1160, which is the number of bytes that can be placed into a single TCP-IP package. It is recommended that each JavaScript file be kept below 1160 bytes to obtain the optimal download time.

In JavaScript, each character is a byte. Therefore, each additional character (whether it is a variable name, function name, or comment) may affect the download speed. The download speed should be optimized as much as possible before JavaScript is deployed.

1. delete comments

2. Delete tabs and spaces

3. Delete all line breaks

4. Replace the variable name

5. ECMAScript Cruncher
ECMAScript Cruncher developed by Thomas Loo (ESC can be downloaded at http://www.saltstorm.net/depo/esc/or 51ajax.com ). ESC is a small Window Shell script.

ECMAScript Cruncher developed by Thomas Loo (ESC can be downloaded ). ESC is a small Window Shell script. To run ESC, you must use Windows. Open a console window and enter the following command:
Cscript ESC. wsf-l [0-4]-ow outputfile. js inputfile. js [inputfile2.js]

In the first part, cscript is a Windows Shell script interpreter. The file name ESC. wsf is the program of ESC. Then there is the compression level. A value ranging from 0 to 4 indicates the level to be optimized. -Ow indicates that the next parameter is the optimized output file name. Finally, the remaining parameters are the JavaScript files to be optimized. You can provide only one file to be optimized, or you can have multiple files (multiple files will be placed in the output file in order after optimization ).

The following four optimization levels are supported by ESC:
0: it is useful to combine multiple files into a single file without changing the script;
1: Delete all comments;
2: In addition to level 1, delete additional tabs and spaces;
3: In addition to level 2, delete the line feed;
4: Except Level 3, replace the variable name.

ESC is good at replacing variable names with meaningless names. It does not change the constructor name, public feature, and public method name.

When using ESC, remember that if a JavaScript references the constructor in another file, Level 4 optimization will replace the reference to the constructor with a meaningless name. The solution is to combine the two files into one, so that the name of the constructor is maintained.

6. other methods to reduce the number of bytes
1) Replace boolean values
Consider the following example:

VarbFound = false; for (var I = 0; I <aTest. length; I ++) {if (aTest [I] = vTest) {bFound = true ;}}

Can be replaced:

VarbFound = 0; for (var I = 0; I if (aTest [I] = vTest) {bFound = 1 ;}}

2) reduce negative detection

If (oTest! = # Ff0000) {// do something} if (oTest! = Null) {// do something} if (oTest! = False) {// do something}

Although these are all correct, using logical non-operators for operations has the same effect.

If (! OTest) {// do something}

7. Use array and object literal

VaraTest = new Array; var aTest = [];

The second line uses the array literal, which has the same effect as the first line, but is much shorter.

Similarly, the object literal volume can be used to save space. The following two rows have a single line of effect, but the object literal volume must be shorter.

VaraTest = new Object; var aTest = {};

If you want to create a general object with some features, you can also use the literal volume as follows:

VaroFruit = new O; oFruit. color = "red"; oFruit. name = "apple ";

The preceding code can be rewritten as follows using the object literal:

VaroFruit = {color: "red", name: "apple "};

1. execution efficiency

1. DOM

1.1 Use DocumentFragment to optimize multiple appends

Note: When multiple dom elements are added, append the elements to DocumentFragment and add DocumentFragment to the page.
This method can reduce the number of times dom elements are rendered on a page. In IE and Fx tests, the efficiency of append1000 elements can be improved by 10%-30%, while that of Fx is more obvious.

Before taking:

For (var I = 0; I <1000; I ++ ){
Var el = document. createElement ('P ');
El. innerHTML = I;
Document. body. appendChild (el );
}

After taking:

Var frag = document. createDocumentFragment ();
For (var I = 0; I <1000; I ++ ){
Var el = document. createElement ('P ');
El. innerHTML = I;
Frag. appendChild (el );
}
Document. body. appendChild (frag );

1.2 replace createElement with template element clone

Note: using a template dom object cloneNode is more efficient than directly creating an element.
Performance improvement is not significant, about 10%. There is no advantage in the create and append operations of less than 100 elements.

Before taking:

Var frag = document. createDocumentFragment ();
For (var I = 0; I <1000; I ++ ){
Var el = document. createElement ('P ');
El. innerHTML = I;
Frag. appendChild (el );
}
Document. body. appendChild (frag );

After taking:

Var frag = document. createDocumentFragment ();
Var pEl = document. getElementsByTagName ('P') [0];
For (var I = 0; I <1000; I ++ ){
Var el = pEl. cloneNode (false );
El. innerHTML = I;
Frag. appendChild (el );
}
Document. body. appendChild (frag );

1.3 Use an innerHTML value assignment instead of building dom elements

Note: When creating a list style based on data, you can set the list container innerHTML to Improve the efficiency by an order of magnitude by building dom elements and appending them to the page.

Before taking:

Var frag = document. createDocumentFragment ();
For (var I = 0; I <1000; I ++ ){
Var el = document. createElement ('P ');
El. innerHTML = I;
Frag. appendChild (el );
}
Document. body. appendChild (frag );

After taking:

Var html = [];
For (var I = 0; I <1000; I ++ ){
Html. push ('<p>' + I + '</p> ');
}
Document. body. innerHTML = html. join ('');

1.4 Use firstChild and nextSibling instead of childNodes to traverse dom elements

Note: The performance can be improved by about 30%-50%. LastChild and previussibling are used for reverse traversal.

Before taking:

Var nodes = element. childNodes;
For (var I = 0, l = nodes. length; I <l; I ++ ){
Var node = nodes [I];
......
}

After taking:

Var node = element. firstChild;
While (node ){
......
Node = node. nextSibling;
}

2. String

2.1 use Array as the StringBuffer to replace String concatenation operations

Note: During String concatenation, IE creates a temporary String object. After testing, in IE, when the concatenated String grows larger, the running efficiency decreases sharply. Both Fx and Opera have optimized the String concatenation operation. After testing, in Fx, the execution time of the join method using Array is about 1.4 times that of the direct String concatenation.

Before taking:

Var now = new Date ();
Var str = '';
For (var I = 0; I <10000; I ++ ){
Str + = '000000 ';
}
Alert (new Date ()-now );

After taking:

Var now = new Date ();
Var strBuffer = [];
For (var I = 0; I <10000; I ++ ){
StrBuffer. push ('123 ');
}
Var str = strBuffer. join ('');
Alert (new Date ()-now );

3. Loop statements

3.1 Save the cyclic control value to a local variable

Note: The length of the array and List objects is saved to a local variable in advance to avoid repeated values in each step of the loop.

Before taking:

Var list = document. getElementsByTagName ('P ');
For (var I = 0; I <list. length; I ++ ){
......
}

After taking:

Var list = document. getElementsByTagName ('P ');
For (var I = 0, l = list. length; I <l; I ++ ){
......
}

3.2 sequential irrelevant time, replaced by while

Note: This method can reduce the use of local variables. Compared with efficiency optimization, the number of characters is optimized. This practice is suspected of being obsessive-compulsive by programmers.

Before taking:

Var arr = [1, 2, 4, 5, 6, 7];
Var sum = 0;
For (var I = 0, l = arr. length; I <l; I ++ ){
Sum + = arr [I];
}

After taking:

Var arr = [1, 2, 4, 5, 6, 7];
Var sum = 0, l = arr. length;
While (l --){
Sum + = arr [l];
}

4. Condition Branch

4.1 sort the condition branches in ascending order of likelihood

Note: This reduces the number of times the interpreter detects conditions.

4.2 When multiple (> 2) condition branches under the same condition subscribe, switch is better than if

Note: switch Branch selection is more efficient than if, especially in IE. For a 4-branch test, the switch execution time in IE is about half of if.

4.3 use the three-object operator to replace the condition Branch

Before taking:

If (a> B ){
Num =;
} Else {
Num = B;
}

After taking:

Num = a> B? A: B;

5. Timer

5.1 When continuous execution is required, setInterval is preferred.

Note: setTimeout initializes a timer every time. SetInterval only initializes a timer at the beginning.

Before taking:

Var timeoutTimes = 0;
Function timeout (){
TimeoutTimes ++;
If (timeoutTimes <10 ){
SetTimeout (timeout, 10 );
}
}
Timeout ();

After taking:

Var intervalTimes = 0;
Function interval (){
IntervalTimes ++;
If (intervalTimes> = 10 ){
ClearInterval (interv );
}
}
Var interv = setInterval (interval, 10 );

5.2 use function instead of string

Note: If the string is used as the parameter of setTimeout and setInterval, the browser will use this string to construct a function.

Before taking:

Var num = 0;
SetTimeout ('num ++ ', 10 );

After taking:

Var num = 0;
Function addNum (){
Num ++;
}
SetTimeout (addNum, 10 );

6. Miscellaneous

6.1 try not to use dynamic syntax Elements

Note: statements such as eval, Function, and execScript are parsed using the javascript parsing engine again, which consumes a lot of execution time.

6.2 duplicate call results are saved to local variables in advance

Note: Avoid calling overhead for multiple values.

Before taking:

Var h1 = element1.clientHeight + num1;
Var h2 = element1.clientHeight + num2;

After taking:

Var eleHeight = element1.clientHeight;
Var h1 = eleHeight + num1;
Var h2 = eleHeight + num2;

6.3 direct usage

Note:
Var a = new Array (param, param,...)-> var a = []
Var foo = new Object ()-> var foo = {}
Var reg = new RegExp ()-> var reg = /.../

6.4 avoid using

Note: although with can shorten the amount of code, it will construct a new scope at runtime.
OperaDev has such an explanation. Using the with statement makes it impossible for the interpreter to optimize the code in the Syntax Parsing phase. This statement cannot be verified.

Before taking:

With (a. B. c. d ){
Property1 = 1;
Property2 = 2;
}

After taking:

Var obj = a. B. c. d;
Obj. property1 = 1;
Obj. property2 = 2;

6.5 clever use | and & boolean operators

Importance:★★★
Before taking:

Function eventHandler (e ){
If (! E) e = window. event;
}

After taking:

Function eventHandler (e ){
E = e | window. event;
}

Before taking:

If (myobj ){
DoSomething (myobj );
}

After taking:

Myobj & doSomething (myobj );

6.6 type conversion

Note:
1). Convert the number to a String and apply "" + 1. performance: ("" +)> String ()>. toString ()> new String ();
2 ). if you do not use parseInt () to convert a floating point to an integer, parseInt () is used to convert a string to a number, rather than between a floating point and an integer. We recommend that you use Math. floor () or Math. round ()
3) We recommend that you explicitly call toString () for custom objects (). After all the possibilities are attempted, the internal operation will try to convert the toString () method of the object to String.

Ii. Memory Management

2.1 circular references

Note: If the circular reference contains a DOM object or ActiveX object, memory leakage will occur. The consequence of Memory leakage is that, even if the page is refreshed before the browser is closed, the memory will not be released by the browser.

Simple loop reference:

Var el = document. getElementById ('myelement ');
Var func = function (){...}
El. func = func;
Func. element = el;

But this usually does not happen. Loop references usually occur when a closure is added to a dom element as an expendo.
For example:

Function init (){

Var el = document. getElementById ('myelement ');
El. onclick = function (){......}
}
Init ();

During init execution, the current context is called context. At this time, context references el, el references function, and function references context. At this time, a circular reference is formed.
The following two methods can solve the problem of loop reference:

1) Empty dom object

Before taking:

Function init (){
Var el = document. getElementById ('myelement ');
El. onclick = function (){......}
}
Init ();

After taking:

Function init (){
Var el = document. getElementById ('myelement ');
El. onclick = function (){......}
El = null;
}

Init ();

Leave el empty. The context does not contain references to dom objects, thus interrupting the circular application.
To return the dom object, use the following method:

Before taking:

Function init (){
Var el = document. getElementById ('myelement ');
El. onclick = function (){......}
Return el;
}
Init ();

After taking:

Function init (){
Var el = document. getElementById ('myelement ');
El. onclick = function (){......}
Try {
Return el;
} Finally {
El = null;
}
}
Init ();

2) construct a new context

Before taking:

Function init (){
Var el = document. getElementById ('myelement ');
El. onclick = function (){......}
}
Init ();

After taking:

Function elClickHandler (){......}
Function init (){
Var el = document. getElementById ('myelement ');
El. onclick = elClickHandler;
}
Init ();

Extract the function to the new context. In this way, the context of the function does not include a reference to el, thus interrupting the circular reference.

2.2 dom objects created using javascript must be appended to the page

Note: In IE, the dom object created by the script will not be recycled if it is not appended to the page and refreshed!
Sample Code:
Function create (){
Var gc = document. getElementById ('gc ');
For (var I = 0; I <5000; I ++)
{
Var el = document. createElement ('div ');
El. innerHTML = "test ";
// You can comment out the following sentence to see the memory changes after the browser clicks the button in the task manager.
Gc. appendChild (el );
}
}

2.3 release the memory occupied by dom elements

Note:
Set innerHTML of the dom element to an empty string to release the memory occupied by its child elements.
In rich applications, users may stay on a page for a long time. You can use this method to release the memory that has accumulated more and more dom elements.

2.4 release javascript objects

Note: In rich applications, memory consumption increases as the number of instantiated objects increases. Therefore, the reference to the object should be released in time so that GC can recycle these memory controls.
Object: obj = null
Object Property: delete obj. myproperty
Array item: Use the splice method of the array to release unused items in the array.

2.5 avoid implicit packing of strings

Note: To Call The string method, such as 'xxx'. length, the browser will perform an implicit packing operation to convert the String into a string object first. We recommend that you use the following method to declare strings that may use the String instance method:
Var myString = new String ('Hello World ');

 

Language related:

Loop

 

Loop is a commonly used control structure. Most things are completed by it. in JavaScript, we can use for (;), while (), for (in) in fact, the efficiency of for (in) in these three loops is very poor, because it needs to query hash keys and should be used as little as possible. For (;) and while loops, while loops are more efficient than for (;). It may be because of the structure of for (;), and you need to jump back frequently.

Local and global variables

Local variables are faster than global variables, because global variables are actually members of global objects, and local variables are placed in the function stack.

 

Do not use Eval

Using eval is equivalent to calling the interpretation engine again at runtime to run the content, which consumes a lot of time. At this time, the closure supported by JavaScript can be used to implement the function template (for details about the closure, refer to the relevant content of functional programming)

 

Reduce Object Search

A. b. c. d. e. You must perform at least four query operations. Check a first, then B in a, and then c in B. So if such expressions repeat, you should try to avoid such expressions as long as possible. You can use local variables to put them in a temporary place for query.

This can be combined with loops, because we often need to loop based on the length of strings and arrays, And the length is usually unchanged, for example, each query. length, an additional operation is required, and var len =. length, then one query is missing.

 

String connection

If it is an append string, it is best to use the s + = anotherStr operation instead of the s = s + anotherStr operation.

To connect multiple strings, use less + =, as shown in figure

S + =;

S + = B;

S + = c;

It should be written as s + = a + B + c;

If it is to collect strings, for example, to perform the + = operation on the same string multiple times, it is best to use a cache. How to use it? Use JavaScript Arrays for collection, and connect using the join method, as shown below:

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 because JavaScript is a dynamic type language and you cannot specify the type of a variable.

1. Convert the number into a string and apply "" + 1. Although it looks ugly, the efficiency is actually the highest. In terms of performance:

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

This is actually a bit similar to the following "Direct Volume". The internal operations that can be used during compilation are faster than those used during running.

String () is an internal function, so the speed is very fast, and. toString () is used to query functions in the prototype, so the speed is inferior. new String () is used to return an exact copy.

2. converting a floating point to an integer is more prone to errors. Many people prefer parseInt (). In fact, parseInt () is used to convert a string to a number, rather than converting between a floating point and an integer, we should use Math. floor () or Math. round ().

In addition, Math is an internal object, which is different from the problem in Object Search in section 2. Therefore, Math. floor () does not actually have many query methods and call times, and the speed is the fastest.

3. for custom objects, if the toString () method is defined for type conversion, we recommend that you explicitly call toString (), because after all the possibilities of internal operations are attempted, will try to convert the toString () method of the object to String, so it is more efficient to directly call this method.

 

Direct usage

In fact, this effect is relatively small and can be ignored. For example, JavaScript supports the use of [param,...] in the past, we used new Array (param, param ,...), the former is directly explained by the engine, and the latter calls an Array internal constructor, so it is a little faster.

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

 

String Traversal

Regular expressions should be used for loop operations on strings, such as replacement and search, because JavaScript itself is slow in the cycle, while regular expression operations are performed using APIs written in C language, good performance.

Advanced object

Custom advanced objects and Date and RegExp objects consume a lot of time during construction. If reusable, cache should be used.

 

DOM related:

Insert HTML

Many users prefer to use document. write in JavaScript to generate content for pages. 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 their HTML code into the page.

 

Object Query

Use [""] to query. items () is faster, which is the same as the previous idea of reducing object search. items () adds a query and function call.

 

Create a DOM Node

Generally, we may use strings to directly write HTML to create nodes.

  1. Code validity cannot be guaranteed

  2. Low string operation efficiency

So we should use document. createElement () method. If there is a ready-made template node in the document, you should use the cloneNode () method. Because after using the createElement () method, you need to set attributes of multiple elements, using cloneNode () can reduce the number of attribute settings-if you need to create many elements, you should first prepare a template node.

 

Timer

If you are targeting constantly running code, you should not use setTimeout, but setInterval. SetTimeout you need to reset a timer each time.

 

Others:

Script Engine

According to my test, Microsoft's JScript is much less efficient than Mozilla's Spidermonkey, whether it is execution speed or memory management, because JScript is not updated now. However, SpiderMonkey cannot use ActiveXObject.

 

File Optimization

File optimization is also an effective method. Deleting all spaces and comments and placing the code in one line can speed up the download process. Note that the download speed is not the resolution speed, if it is local, comments and spaces do not affect the speed of interpretation and execution.

 

Batch increaseDom

Try to use the innerHTML modification method instead of the appendChild method. Because innerHTML has a lower overhead, faster speed, and more memory security.

One thing to note is that when you use the innerHTML method to add, you must not use the innerHTML + = method in the loop, which will slow down the speed. Instead, you should use the array cache in the middle, call xx after the loop ends. innerHTML = array. join (''); or at least save to string and insert it into innerHTML.

This method is used to optimize the user list, and the loading speed is doubled.

 

Single increaseDom

This refers to the situation where a new node is loaded to a node with constantly changing content. For nodes with stable content, it is no problem to add any content. however, for nodes with dynamic content, try to use dom append to add subnodes to them.

This is because dom append does not affect other nodes. If the innerHTML attribute is modified, all child nodes of the parent node will be removed from the dom tree, then, the sub-node dom tree is re-painted based on the new innerHTML value. All events registered with the original sub-node will also become invalid.

To sum up, if the innerHTML + = code appears on a node with dynamic content, you should check whether there is a problem.

 

CreateDomNode

Creating a dom node using createElement has an important detail: After executing the createElement code, append it to the dom tree; otherwise, if you assign attributes and innerHTML operations to the isolated node before it is loaded to the dom tree, the memory of the dom fragment cannot be recycled. this inconspicuous detail will cause a memory disaster once a large number of dom addition and deletion operations are encountered.

 

DeleteDomNode

Before deleting a dom node, you must delete the events registered on the node, whether registered in observe or attachEvent mode. Otherwise, memory cannot be recycled.

In addition, the latter should be selected between removeChild and innerHTML = '', because in sIEve (Memory Leak Monitoring Tool), the result of monitoring is that removeChild cannot effectively release dom nodes.

 

Create event listening

The existing js library uses the observe method to create event listening, which isolates the circular reference between the dom object and the event processing function. Therefore, we should try to use this method to create event listening.

 

Listen to dynamic elements

Dom events are bubble up by default. The events that occur in the subnode can be handled by the parent node. the target/srcElement of the Event is still the deepest subnode that generates the Event. in this way, when the content is dynamically added and the child nodes need the same event processing function, you can refer to the event registration on the parent node, in this way, you do not need to register event listening for each subnode.

At the same time, this avoids memory that cannot be recycled. even if you use the Prototype observe method to register events and call stopObserving before deleting a node, a small amount of memory cannot be recycled. Therefore, you should register event listening for dom nodes as few as possible.

Therefore, when an event is registered in a loop in the code, it is time for us to consider the event escalation mechanism.

 

HTMLPurification

HTML purification reflects the idea of taking responsibility for each other. HTML is only used for display and should not display attributes unrelated to display, such as onclick events, such as custom object attributes.

The preceding method can be used to avoid an event. An object attribute refers to a scenario in which the dynamically added content usually corresponds to an object, for example, in the user list of the chat room, each dom node that shows the user has a user object corresponding to it. In this way, only one id attribute corresponds to the user object in html, other information should be obtained through the user object.

 

Note: Memory leakage of JavaScript in IE

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.