2010-02-02

JS performance test - scope and named functions - Analytics

JS performance test - scope and named functions - Analytics

JavaScript global scope vs. encapsulated, variable as holder of anonymous function vs. named functions.

This stress test gave quite a surprise. Popular JS coding practices and dominant opinion appeared to be completely wrong. Probably because of rapid evolution of JS engines. Or maybe the habit to rely on reasonable guesses of respected people.

Idea

To create the test came from inconvenience of using anonymous code. There are many code maintenance reasons to switch to named functions code but on the net many respected JS gurus are promoting the anonymous functions use and most popular JS library are filled with such code. Is there any compromise with widely accepted pattern? If the speed lost is not big, choice could be balanced.
Appeared I was wrong in my expectations. All tests shown there is no need for balance. Old fashion coding style shall be considered as bad practice and removed from code as harmful.

Conclusion

  • Use the named function instead of variable initialized with anonymous function.
  • Global functions given much boost in performance. Reduce the use of scoped functions for initialization code - page initialization code wrapped into own scope way slower of global functions declaration.
  • Use SCRIPT dom node code injection instead of slower eval().
Certainly, everything has own limitations. The rescoping is dangerous from code maintenance side technique and shall be automated by compiler/compressor at the last stage of development cycle - within web app, not the reusable library. The results are different for different browsers and creation of custom build for browser is more efficient of generic one: i.e. Firefox is not sensitive to local/global scope while Opera significantly slower for scoped functions...
The Web 2.0 application consists not just from JS initialization. In fact, it is just 1st row developer facing for page load and run speed. In most cases frameworks are "good enough" on their own. The problems usually appeared in heavy apps utilized several of them simultaneously.

Test.

Initially had simple evaluation purpose for anonymous functions replacement with named ones. Code maintenance is badly damaged by such coding style and test shall show if performance is not a real issue.
For test JSP renders identical JS code with only difference on function declaration signature
Var as reference to anonymous function:
var FunctionScr3Var27=function(){ window.RealCount++; }
Function - local named function:
var function FunctionScr3Var27(){ window.RealCount++; }
The test result could be impacted as the function call as function initialization. To distinct those cases at least somehow, from whole set of declared functions, there is Half option to call each second one. Beer on me if you could tell how to call function without its initialization :)
Another thought was about having the size of rendered file in stats. XHR gives its string value and length. And that could be used for eval() timing. The known fact is “eval() slower of SCRIPT tag”. Question is how much?
Not sure what given me the idea to run the same test inside of function scope in addition to just global one.  But surprising results came out of it.

Speculation on statistics.

1. Anonymous function vs. named functions. Test cases: 0,1,4,5 versus 2,3,6,7
IE: functions are 10-200% faster
Opera: run time so damn fast that no way to detect the difference. Same.
Chrome: function 10% faster in local scope. Same
FF: on edge of detection. Same 
Safari: Same


2. Global scope vs. wrapped in function. Test cases: 0,1,2,3 vs 4,5,6,7. Global faster:
IE,Opera: 20-300%
Chrome: in eval() local is enormously slow, on run is on the edge of detection. Same w/ favor to global scope.
FF: in eval() local 50% slower, in run untraceable. Same w/ favor to global scope.
Safari:10%


3.      Eval() vs SCRIPT . eval looses:
IE: 200-400%
Opera: 1000%
Chrome 10-300%, 1000% for local scope
FF:    700%
Safari  10%


4.      Half vs. full set. Meaning TBD. IMHO, that is just JS engine capabilities test,
IE: 20-200%
Opera, Chrome: 5%
FF +=5% (?)
Safari 50% (expected)


5.      Browsers overall
Opera is 6 times slower for JS load and parsing time and as result, overall.


JS engine – run time in ms:
Safari: 924 ( worst ).
 FF:     23
 IE:     17
 Opera:  16
 Chrome: 10 (best)


JS engine – eval(), ms
 Safari: 950
 Opera:  560
 Chrome: 263
 FF:     170
 IE:      38(best)

PS It would be nice to integrate real-time charting, but there is not enough bandwidth on my side. Any sponsors or volunteers?

Links

Happy coding!
Sasha

2010-02-01

JS performance test - scope and named functions - DATA

There is a data collected using tests discussed before.


















































Please, share  your data collected on various browsers/platforms in comments
for tests 500 | 1000 | 3000 | 10000
Or you could use customized test on your own from given sources:

Sources: index.jsp - UI file | AnonymousJsVsNamed.js.jsp - JS rendering JSP

Sasha