When testing the performance of one JavaScript project, I noticed a very peculiar behavior - JavaScript member access performance seems to be heavily influenced by the scope they are in. I wrote a few performance tests, and the results were different by multiple orders of magnitude.
I tested on Windows 10 64-bit, using these browsers:
- Google Chrome, version 49.0.2623.75 m - uses the V8 JavaScript engine
- Mozilla Firefox, version 44.0.2 - uses the SpiderMonkey JavaScript engine
- Microsoft Edge, version 25.10586 - uses the Chakra JavaScript engine
Here are the most relevant tests I ran and their respective results:
// Code running on global scope, accessing a variable on global scope
// Google Chrome: 63000 ms.
// Mozilla Firefox: 57000 ms.
// Microsoft Edge: 21000 ms.
var begin = performance.now();
var i;
for(i = 0; i < 100000000; i++) { }
var end = performance.now();
console.log(end - begin + " ms.");
// Code running on local scope, accessing a variable on global scope
// Google Chrome: 61500 ms.
// Mozilla Firefox: 47500 ms.
// Microsoft Edge: 22000 ms.
var begin = performance.now();
var i;
(function() {
for(i = 0; i < 100000000; i++) { }
})();
var end = performance.now();
console.log(end - begin + " ms.");
// Code running on local scope, accessing a variable on local scope
// Google Chrome: 50 ms.
// Mozilla Firefox: 28 ms.
// Microsoft Edge: 245 ms.
var begin = performance.now();
(function() {
var i;
for(i = 0; i < 100000000; i++) { }
})();
var end = performance.now();
console.log(end - begin + " ms.");
The difference between code running in local and global scopes was within the margin of error, although Firefox did seem to get a pretty consistent 20% performance boost running in local scope.
The biggest surprise was accessing a variable on a local scope, it was 1200 to 1600 times faster on Chrome and Firefox, and 90 times faster on Edge.
Why would this be the case, on three different browsers / JavaScript engines?