JavaScript Optimization FAQs
Speed Up Scripts and Web sites with JavaScript Optimization Strategies
Dr. E. Garcia
Mi Islita.com
Email | Last Update: 09/24/05
Topics
Why JavaScript Optimization
JavaScript Optimization Resources
Assumptions and Conventions
Optimization Strategies
JavaScript Optimization FAQs
References
Why JavaScript Optimization
JavaScript Optimization is an exciting branch of website optimization that is changing the way programs are written. Did you know that many Javascript codes, tutorials and reference books of so-called "experts" contain unoptimized, sloppy code? Instead of lecturing on programming practices we show you how to
- speed up JavaScript programs and sites.
- avoid the "great speed offenders".
- say NO to bad programing habits.
JavaScript Optimization Resources
Before submitting a question on optimization or scripting issues, please review the assumptions, conventions and nomenclature utilized throughout this document. You may also want to consult References 1 - 14, especially Andy King and Danny Goodman authority books, from which many answers have been adapted.
- Andy King, Speed Up Your Site: Web Site Optimization, 1st Edition, (New Riders). This is a Must-Have/Must-Read web site optimization reference book. Mi Islita recommends this book to webmasters, web designers, optimizers and programmers. Unlike Danny Goodman's book, this book is not about how to learn JavaScript but about optimization techniques. The book touches many optimization fields such as HTML, XHTML, CSS, file size, graphic and sound files, JavaScript, meta tags, bandwidth usage, networking resources, etc. It is not a book for beginners.
- Danny Goodman, JavaScript Bible, 4th Edition; IDG Books Worldwide, Inc. As its name indicates, this is The Official Bible of all JavaScripters. Mi Islita highly recommends this book. Unlike Andy King's book, this book is not about optimization but about JavaScript programming. Considered by many as The Reference, this is a book for beginners and advanced programmers. Like the good wine, it gets better with each edition.
Assumptions and Conventions
- Audience: We assume readers know JavaScript.
- Implicit: The line "// do something with ..." is a place holder for additional code and should not be taken for comments.
- Note: Some lines start with "<" followed by a space. This is done to force your browser to displaying the code. This extra space is not required in the working code. The script language attribute (e.g, language="javascript") has been deprecated by the W3C.
Optimization Strategies
- Notations: We use short notations.
- Techniques: Precaching techniques are used.
- DOM: Document Object Model (DOM) interactions are minimized by precaching "dot calls". Generally speaking, scripts run faster when DOM calls are minimized or avoided.
- Flexibility: Some techniques require more typing (more lines of code). A speed vs size tradeoff is involved. Keep in mind that optimization is the art of finding a happy medium.
Submit a question.
JavaScript Optimization FAQs
How do you...
- optimize a dynamic window, so only one window is created and reused?
This is a nice usability and javascript optimization question. At times, one can see sites with too many remote windows coded. These windows need to be closed, eventually. Replace all those codes with just one reusable code. The first two lines insure that two windows don't open at the same time.For example, for two windows launched by clicking two corresponding links, create a window object and do this var w=new Object; w.closed=true; function pop(x) {if (!w.closed){w.close();} if(x==1){url='http://.../link1.html';} if(x==2){url='http://.../link2.html';} w=window.open('','','width=400px,height=400px'); w.document.location.href=url; w.focus(); } var t=''; t+='< a href="javascript:pop(x=1)">Link 1< /a> |'; t+='< a href="javascript:pop(x=2)">Link 2< /a>';document.write(t);Add as many links as necessary. For pages with large number of remote windows, use a link array. Either way, please don't do this // multiple dynamic windows coded... - declare variables and comments? Whenever possible, do not declare variables in long notation and implicitly. Keep script comments to a minimun or avoid them altogether, especially inside functions, loops and arrays. These habits unnecessarily slow down script execution and increase file size. For instance,
Do this function hey() { var x=10; var y=5; // do something with x and y } Not this function hey() { var x_variable, y_variable; x_variable=10; /*This variable does ...*/ y_variable=5; /*This variable is for ...*/ // do something with x and y } - maximize object resolution speed and minimize scope chain?
Do this var url=window.location.href; Not this var url=location.href; or this url=location;
- speed up object-property lookups inside a loop?
One of the "great offenders"! Whenever possible, avoid global variables. Use the var keyword to declare them as local. Local variables are searched first and run faster than global variables. Also precache chain lookups. Scope chain lookups inside loops are time consuming. Avoid whitespace and comments inside loops. These practices are common "speed offender", found in many online scripts, favelets (bookmarklets) and even in many JavaScript books.Do this var x=m.n.p.q; for(var i=0;i<100;i++) { x(i); // do something with i } or this var n=x.length; for(var i=0;i<n;i++) { // do something with i } Not this for(i = 0; i < 100; i++) { m.n.p.q(i); // do something with i } neither this for(i = 0; i < x.length; i++) { // do something with i } - Reduce the number of dot lookups ("dot calls") using forms?
Whenever possible, use an index into the object array since accessing a named property or object requires a lookup itself. Multiple forms in a document must be addressed as follow: forms[0], forms[1], forms[2] and so on and as found by the browser. Do not use "with" in JavaScript. This command has been deprecated. The command extends the scope chain with a computed object, executes a statement with this longer chain, and then restores the original scope chain. This costs execution time. For pages with only one formDo this var x=document.forms[0]; var m=x.m.value; var n=x.n.value; var o=x.o.value; However, if you need to name the form, (e.g. a form named "myform") try this var x=document.myform; var m=x.m.value; var n=x.n.value; var o=x.o.value; But not this var m=document.myform.m.value; var n=document.myform.n.value; var o=document.myform.o.value; Neither this with(document.myform) { var m=m.value; var n=n.value; var o=o.value; } - minimize lookups inside a loop involving arrays?
Another "great offender"! Often we see scripts in which an array length is used as a loop conditional and evaluated over and over until the condition cannot be sustained. This practice is a common "speed offender" found in many JavaScript books, tutorials and script resources. It's a shame.Do this var A=new Array(); var n=A.length; for(var i=0;i<n;i++) { // do something with A[i] } Not this
A=new Array(); for(i = 0; i < A.length; i++) { // do something with A[i] } - minimize the use of document.write call statements?
More "great offenders"! We call this one the document-dot-write syndrome because many sites are plagued with it. This "speed offender" is found in many JavaScript repository sites, "expert" sites, tutorial sites and in SEO-"optimized" pages. Each document.write is a call to the browser DOM. Your script needs only one call, which can then be pre-cached as a variable.Do this var t=''; t+='string1'; t+='string2';
document.write(t);or this var t='string1'+'string2';document.write(t);or thisvar t=document.write;t('string1'); t('string2'); But (please, please, please) Don't do thisdocument.write('string1'); document.write('string2'); // more document.write goes here, and here, and here. - dynamically call several external files?
Do this var x='< script type="text/javascript" src='; var y='><\/script>'; var t=''; t+= x+'file1.js'+y; t+= x+'file2.js'+y; t+= x+'fileA.txt'+y;
document.write(t);Not thisdocument.write('< script src=file1.js><\/script>'); document.write('< script src=file2.js><\/script>'); document.write('< script src=fileA.txt><\/script>'); - avoid unnecessary DOM references in objects?
In JavaScript 1.2 you can use object literals.Do this house={ howold: "brand new", color: "red", rooms: 3, doors: 4, bathrooms: 2 } Not this house=new Object(); house.howold="brand new"; house.color="red"; house.rooms=3; house.doors=4; house.bathrooms=2; - minimize Math lookups, for example, when rounding off quantities to a certain number of decimal places; e.g., dp=2?
Precache the Math object and its method(s). For exampleDo this var dp=2; var m=Math.pow(10,dp); var x=Math.round; var n1=x(177.789753*m)/m; var n2=x(63.3697532*m)/m; var n3=x(9.4191153*m)/m; var n4=x(15.5053*m)/m; Not this var dp=2; var n1=Math.round(177.789753*Math.pow(10,dp))/Math.pow(10,dp); var n2=Math.round(63.3697532*Math.pow(10,dp))/Math.pow(10,dp); var n3=Math.round(9.4191153*Math.pow(10,dp))/Math.pow(10,dp); var n4=Math.round(15.5053*Math.pow(10,dp))/Math.pow(10,dp); Note. This solution was provided before the inception of the new to.Precision() and to.Fixed() methods. These methods simplify even more the script. See examples in our JavaScript Math FAQs page.
- caching frequently used global objects or property references?
Math is a global object. Caching global or frequently used objects or properties simplifies the calculations. Declaring a counter in short notation involves less typing (e.g., x+=m is the same as x=x+m). For instance,Do this var d=17; var n=100; var x=0; var m=Math.sin(d)*10; for (var i=0;i<n;i++) {x+=m;} Not this var d=17; var n=100; var x=0; for (var i=0;i<n;i++) {x=x+Math.sin(d)*10;} - avoid the use of for-to loops?
Use do-while loops, flipped and with reverse counting. These type of do-while loops can be 4 time faster than for-to loops. For instanceDo this function do_loop() { var i=10; do {// do something with} while(--i); } If you need to stop the loop at a given point, use a conditional break, e.g. function do_loop() { var i=10; do {// do something with if(i<=5){break} } while(--i); } Not this function for_loop() { for(var i=0;i<10; i++) {// do something with i} } - execute a do-while loop with flipped and reverse counting but counting up, not down (as required with many banners and paid links stored in JavaScript arrays)?
Use a delta counter. (In the example below, var i=k-n is a delta counter)Do this var n=5; var k=n; do { var i=k-n; // do something with i; } while(--n); With an array, do this var m=new Array(); var n=m.length; var k=n; do { var i=k-n; // do something with m[i]; } while(--n);
NOTE: Unlike incremental loops, this loop does not compares a conditional statement. The while condition assumes that n is greater than zero and simply runs from n to 1. However, the delta counter itself runs from 0 to n - 1, precisely as a JavaScript array runs. With some modifications, a delta counter can be used with any do-while loop with flipped and reverse counting, but counting up, not down. Sounds contradictory :) We came up with the delta counter idea by inspection. Any suggestion or improvement is welcome. - dynamically call an ActiveX control to avoid infringement of the Eolas patent?
Do this var t=document.write; t('< OBJECT CLASSID="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6">'); t('< PARAM NAME="URL" VALUE="http://msdn.microsoft.com/workshop/'); t('samples/author/dhtml/media/drums.wav"/>< /OBJECT>'); Not this suggested solutiondocument.write('< OBJECT CLASSID="CLSID:6BF52A52-394A- 11d3-B153-00C04F79FAA6">'); document.write('< PARAM NAME="URL" VALUE="http://msdn.microsoft.com/workshop/'); document.write('samples/author/dhtml/media/drums.wav"/>< /OBJECT>');Note. Sorry, Microsoft! This solution is fair, but is not script-optimized for speed.
References
- Andy King, Speed Up Your Site: Web Site Optimization, 1st Edition, (New Riders) King is the founder and newsletter editor of WebReference.com. The companion Web site for his book can be found at:
www.websiteoptimization.com
Samples can be found at
http://webreference.com/programming/optimize/speedup/chap10/ - Danny Goodman, JavaScript Bible,
4th Edition; IDG Books Worldwide, Inc. Goodman is a recognized expert and scripter. - Jon Bentley, Jon Bentley's Programming Pearls, 2nd ed. (Addison-Wesley, 1999) and More Programming Pearls: Confessions of a Coder (Addison-Wesley, 1988)
- Brian Kernighan and Rob Pike's The Practice of Programming (Addison-Wesley, 1999) Kernighan describes best programming practices.
- Donald Knuth's The Art of Computer Programming Series (Addison-Wesley, 1998)
- Steve C. McConnell Code Complete: A Practical Handbook of Software Construction (Microsoft Press, 1993)
- Geoffrey Fox, "JavaScript Performance Issues," Online Seminar, Northeast Parallel Architectures Center [online], (Syracuse, NY: Syracuse University, 1999), available from the Internet at http://www.npac.syr.edu/users/gcf/forcps616javascript/ msrcobjectsapril99/tsld022.htm
- Martin Fowler Refactoring: Improving the Design of Existing Code (Addison-Wesley, 1999) http://www.refactoring.com/catalog/ Martin Fowler's catalog of refactoring techniques.
- http://www.cs.bell-labs.com/cm/cs/pearls/apprules.html Jon Bentley's rules for code tuning.
- http://home.earthlink.net/~kendrasg/info/js_opt/ Jeff Greenburg's JavaScript speed-optimization tests.
- http://www.xp123.com/xplor/xp0002d/ William Wake's refactorings from Bentley's Writing Efficient Programs.
- http://mozilla.org/performance/jsprofiler.html
- http://www.hacksrus.com/~ginda/venkman/profiles/
- http://www.javascript-games.org

