Loop Optimization
console.log("You've found the following necklaces:"); for(var i = 0; i < treasureChest.necklaces.length; i++) { console.log(treasureChest.necklaces[i]); }
For each potential loop cycle, the program will need to find and retrieve:
1. the value of i
2. the treasureChest object
3. the necklaces property
4. the array pointed to by the property
5. the length property of the array
1st optimization: Use "cached values" to curtail lengthy, repetitive access to the same data.
console.log("You've found the following necklaces:"); var x = treasureChest.necklaces.length; for(var i = 0; i < x; i++) { console.log(treasureChest.necklaces[i]); }
Memory access during loop control now only needs to:
1. retrieve the value of i
2. retrieve the value of x
Then, add in our one-time cost in creating x:
1. creating the variable x in memory.
2-5. the 4 steps finding the value of length
Some arithmetic calculations:
5 steps x (10,000 executed loops + 1 check to stop) = 50,005 memory access steps
2 steps x (10,000 executed loops + 1 check to stop) = 20,002 memory access steps
+ 5 extra steps for x = 20,007 memory access steps
~30,000 steps of savings in result!
2nd optimization: place new control variable inside the first loop parameter.
console.log("You've found the following necklaces:"); for(var i = 0, x = treasureChest.necklaces.length; i < x; i++) { console.log(treasureChest.necklaces[i]); }
3rd optimization: avoid repetitive access of a property within an object
console.log("You've found the following necklaces:"); var list = treasureChest.necklaces; for(var i = 0, x = treasureChest.necklaces.length; i < x; i++) { console.log(list[i]); }
Note: Now we've avoided the extra step of accessing the treasureChest in each cycle.
Script Execution
Problem: Scripts encountered high in the
or tags of an HTML page can have adverse effects.Solution One: Scripts that are not essential to immediate loading of the page should be moved as low as possible.
Solution Two: With external files, the HTML5 async attribute will allow the rest of the page to load before the script runs.
Short Performance Tips
USE A PROTOTYPE FOR SHARED STUFF:
Beware of loading up individual objects with code that easily could be held and sourced elsewhere.
Candidate for optimization:
function SignalFire( ID, startingLogs ){ this.fireID = ID; this.logsLeft = startingLogs; this.addLogs = function ( numLogs ){ this.logsLeft += numLogs; } this.lightFire = function () { alert("Whoooosh!"); } this.smokeSignal = function () { if (this.logStatus < this.message.length / 10){ alert("Not enough fuel to send " + "the current message!); } else { this.lightFire(); var x = this.message.length; for(var i = 0; iGive all common methods that a "class" of objects will use to the constructor’s prototype.
function SignalFire( ID, startingLogs ){ this.fireID = ID; this.logsLeft = startingLogs; } SignalFire.prototype = { this.addLogs = function ( numLogs ){ this.logsLeft += numLogs; } this.lightFire = function () { alert("Whoooosh!"); } this.smokeSignal = function () { if (this.logStatus < this.message.length / 10){ alert("Not enough fuel to send " + "the current message!); } else { this.lightFire(); var x = this.message.length; for(var i = 0; iUSE A DOCUMENT FRAGMENT TO INSERT ADDITIONS ALL AT ONCE:
Adding DOM elements individually ain't always speedy, since each new addition to the DOM causes document "reflow", which can really hinder user experience.var list = document.getElementById("kotwList"); var kotw = ["Jenna Rangespike", "Neric Farthing", "Darkin Stonefield"]; for (var i = 0, x = kotw.length; iNote: Each time the list is appended, we access the DOM and cause an entire document reflow. Not as speedy as we’d like, especially if our list was huge...
Solution:
Use a document fragment to insert additions all at once. Fragments are invisible containers that hold multiple DOM elements without being a node itself.var list = document.getElementById("kotwList"); var kotw = ["Jenna Rangespike", "Neric Farthing", "Darkin Stonefield"]; var fragment = document.createDocumentFragment(); for (var i = 0, x = kotw.length; iNote: Now we add each new li element to the staging fragment, instead of to the document itself. And append all of our new text nodes in one fell swoop, using only one DOM touch!
DECLARE VARIABLES AS FEW TIMES AS POSSIBLE
Every var keyword adds a look-up for the JavaScript parser that can be avoided with comma extensions. Commas used after an initial declaration can signal that you'll declare further variables.Declaring in loops should thus be used with caution. Anticipate variable needs to avoid the processor burden of creating a new var over and over.
According to all these statements code transforms to:
var list = document.getElementById("kotwList"), kotw = ["Jenna Rangespike", "Neric Farthing", "Darkin Stonefield"], fragment = document.createDocumentFragment(), element; for (var i = 0, x = kotw.length; iEFFICIENT CHOICES FOR STRING CONCATENATION
Different string building methods will yield different results in terms of execution speed.The standard concatenation operator has been optimized in most modern browser versions, and is an ideal choice for a small number of string concatenations.
var turn = ""; turn += knight; turn += action; turn += weapon;For concatenations over an array's contents, use the join() method inherited from the Array prototype.
var newPageBuild = [ "", "", "", "",! ***a hundred or more other html elements***,! "", “", "" ]; page = newPageBuild.join("\n");
Note: The join method concatenates each index of the array, "joined" by any string parameter you pass in. In addition to being faster in tests than many String methods, it is also easier to read.