Share my methods and code for optimizing JavaScript

Source: Internet
Author: User
Tags object closure functions garbage collection variables string variable window
Author: Gregory Baker, GMail software engineer and Erik Arvidsson, Google Chrome software engineer need experience: JavaScript related work knowledge

Author: Gregory Baker, GMail software engineer and Erik Arvidsson, Google Chrome software engineer

Experience Required: JavaScript Related work knowledge

Client-side scripting can make your application more dynamic and active, but the browser's parsing of the code can create an efficiency problem, and the performance difference varies between clients. Here we discuss and give some tips and best practices for optimizing your JavaScript code.

Using strings

String concatenation operations can have a significant impact on the garbage collection of Internet Explorer 6 and 7. Although this problem is addressed in Internet Explorer 8-string concatenation is a bit more efficient in IE8 and other non-IE browsers such as Chrome-if a large portion of your users are using Internet Explorer 6 or 7, you need to be very careful about how you build strings.

The following sample code is available:

The following are the referenced contents:

var verylongmessage =
' This is a long string that due to our strict line length limit of ' +
Maxcharsperline +
' Characters per line must to be wrapped. ' +
Percentwhodislike +
'% of engineers dislike this rule. The line length limit are for ' +
' style purposes, but we don ' t want it to have a performance impact. ' +
' So the question are how should we do the wrapping? '


Try to use join () in the way that you are connecting:

The following are the referenced contents:

var verylongmessage =
[' This is a long string that due to our strict line length limit of ',
Maxcharsperline,
' Characters per line must to be wrapped. ',
Percentwhodislike,
'% of engineers dislike this rule. The line length limit are for ',
' style purposes, but we don ' t want it to have a performance impact. ',
' So the question are how should we do the wrapping? '
].join ();


Similarly, it is inefficient to build strings in conditional statements and loops in a connected way. The wrong way:

The following are the referenced contents:

var fibonaccistr = ' Top 20 Fibonacci numbers ';
for (var i = 0; i < i++) {
Fibonaccistr + = i + ' = ' + Fibonacci (i) + '
';
}


The right approach:

The following are the referenced contents:
var strbuilder = [' Top 20 Fibonacci numbers: '];
for (var i = 0; i < i++) {
Strbuilder.push (i, ' = ', Fibonacci (i));
}
var fibonaccistr = Strbuilder.join (');


Building a string generated by an auxiliary function

Build long strings into functions by passing a string builder (which can be an array or auxiliary class) to avoid a string that holds temporary results.

For example, suppose Buildmenuitemhtml_ needs to build a string with literal strings and variables, and uses a string builder internally to use:

The following are the referenced contents:

var strbuilder = [];
for (var i = 0; i < menuitems.length; i++) {
Strbuilder.push (This.buildmenuitemhtml_ (menuitems[i));
}
var menuhtml = Strbuilder.join ();

Why not use:

var strbuilder = [];
for (var i = 0; i < menuitems.length; i++) {
This.buildmenuitem_ (Menuitems[i], strbuilder);
}
var menuhtml = Strbuilder.join ();


Ways to define Classes

The following code is inefficient because each construction baz. Bar, a new function and closure (closure) are created for Foo:

The following are the referenced contents:

Baz. Bar = function () {
Constructor code
This.foo = function () {
Method code
};
}

The recommended way is:

Baz. Bar = function () {
Constructor code
};

Baz. Bar.prototype.foo = function () {
Method code
};


In this way, no matter how many Baz are constructed. Bar instance, only one function is created for Foo, and no closures are created.

Initializing instance variables

A variable declaration/initialization code with an initialization value of a value type (such as a numeric, Boolean, null, undefined, or string value) is placed directly in the prototype prototype. This avoids the unnecessary running of initialization code every time the constructor is invoked. (This method cannot be applied to an instance variable where the initialization value is determined by the constructor parameter or is not determined by the construction state.) )

For example, rather than write:

The following are the referenced contents:

Foo. Bar = function () {
this.prop1_ = 4;
This.prop2_ = true;
this.prop3_ = [];
this.prop4_ = ' blah ';
};

Why not write:

Foo. Bar = function () {
this.prop3_ = [];
};

Foo. Bar.prototype.prop1_ = 4;

Foo. Bar.prototype.prop2_ = true;

Foo. Bar.prototype.prop4_ = ' blah ';


Use closures carefully (closure)

Closures are a powerful and useful feature of JavaScript; However, they also have bad places, including:

They are the most common source of memory leaks.

Creating a closure is significantly slower than creating an inline function without a closure, which is slower than reusing a static function. For example:

The following are the referenced contents:
function Setupalerttimeout () {
var msg = ' message to display ';
Window.settimeout (function () {alert (msg);}, 100);
}
Slower than the following code:

function Setupalerttimeout () {
Window.settimeout (function () {
var msg = ' message to display ';
Alert (msg);
}, 100);
}
More slowly than the following code:

function Alertmsg () {
var msg = ' message to display ';
Alert (msg);
}

function Setupalerttimeout () {
Window.settimeout (alertmsg, 100);
}


They increase the level of the scope chain (scope chain). When a browser resolves an attribute, each level of the scope chain must be checked once. In the following example:

The following are the referenced contents:
var a = ' a ';

function Createfunctionwithclosure () {
var b = ' B ';
return function () {
var c = ' C ';
A
b
C
};
}

var f = createfunctionwithclosure ();
f ();


When F is invoked, reference A is slower than reference B, which is slower than referencing C.

See Ie+jscript Performance Recommendations Part 3:javascript Code inefficiencies For more information about using closures in IE.

Avoid using with

Avoid using with in your code. It has a very bad effect on performance because it modifies the scope chain, making it expensive to find variables in other scopes.

Avoid browser memory leaks

Memory leaks are a common problem for WEB applications, which can cause serious performance problems. When the browser's memory usage goes up, your Web application, along with other parts of the user's system, slows down. The most common memory leaks for WEB applications are the circular references between the JavaScript scripting engine and the C + + object implementations of the browser DOM (for example, between the JavaScript scripting engine and the COM infrastructure of Internet Explorer, or Jav Ascript engine and Firefox's XPCOM infrastructure).

Here are some rules of thumb to avoid memory leaks:

Use an event system to attach an event handler function

The most common circular reference mode [DOM element--event handler--closure scope--dom] is discussed in this MSDN blog article. To avoid this problem, you can use a rigorously tested event system to attach event-handling functions such as Google doctype, Dojo, or JQuery.

In addition, the use of inline (inline) event-handling functions in IE can result in another type of leakage. This is not a common circular reference leak, but a leak of a temporary anonymous script object in memory. For more information, see the "DOM Insertion Order leak model" for understanding and resolving IE leak mode (understanding and solving Internet Explorer leak Patterns) (DOM insertion orders leak M Odel) "section, and another example in the JavaScript Kit tutorial.

Avoid using extended (expando) Properties

An extended property is any JavaScript attribute attached to a DOM element and is a common cause of circular references. You can use extended attributes without causing a memory leak, but it's easy to accidentally introduce a leak. This leaked pattern is the "DOM element--" extended attribute--"middle object--" DOM element. The best way is to avoid using them. If you want to use them, just use a simple value type. If you want a simple type, set it to NULL when you no longer need to extend the property. See the "Circular references (circular References)" section in the understanding and resolution of the IE leak mode (understanding and solving Internet Explorer leak Patterns).



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.