Avoid eval() in latest JavaScript engines

I've been suprised by the results of a JavaScript engine test recently published by the german c't magazine.

They report a huge performance gain achieved by the latest JavaScript engines (except for IE...) by compiling JavaScript at load time. Unfortunately compilation can not be done for code loaded through eval().

In my understanding all Echo code is loaded through eval() - except bootloader and core libraries. I know the benefits of lazy code loading - but is this worth the performance loss?

Has anybody some experience regarding this topic?

tliebeck's picture

Interesting...have a link?

Interesting...have a link?

aschild's picture

I don't have the articel at

I don't have the articel at hands for the moment, but here another links on the topic:

http://dev.opera.com/articles/view/efficient-javascript/?page=2 (Opera site seems to be down currently)

André

Javascript engine performance comparison

Have a look at the (german) online article at http://www.heise.de/kiosk/archiv/ct/2009/18/160_kiosk.

As a conclusion, the article says

  • Do not eval() as the engines can not JIT compile this code (the reason for this is not explained)
  • Pass function reference to timers, etc. Do not pass code directly - setTimeout('alert("timeout")', 1000) - as this uses eval() to execute
  • Always prepend a new variable with 'var' keyword to avoid symbol lookups along the nested scopes
  • Overall performance of test cases: Safari 4 far ahead of Chrome 2, tightly followed by Firefox 3.5, Opera at the far tail of all JIT compiling engines. IE8 has not even started...
  • Concrete examples: get DOM element by id: IE8 50% slower than Safari, get DOM create/clone DOM elements: IE8 10 times slower than Safari, insert into DOM: IE8 20 times slower than Safari, function pointer: IE8 70 times slower than Safari, function inlining: IE8 11 times slower than Safari, etc.
  • Assign all styles together using setAttribute('style', ...)
  • Clone DOM elements rather than create new ones

aschild's picture

Here the links in the

tliebeck's picture

BTW, we're already doing

BTW, we're already doing everything there except for using eval(). eval() is only used to load additional libraries. In the case of server-side apps, all the core libraries are loaded in a standard script element, i.e. Core.js, Core.Web.js, Application.js, Render.js, Sync.js, Serial.js, Client.js, RemoteClient.js, FreeClient.js, Arc.js and DebugConsole.js.

tliebeck's picture

Well, I think between the

Well, I think between the line numbers issue and this, eval() needs to go. That means implementing a new method, and testing with eleventy different browser configurations. eval() in its current form was chosen in part because it works seamlessly with all browsers, and other options did not.

The critical requirement for dynamically loading JS modules is that they be loaded in the specified order and that we receive notification when the loading has completed. Any approach that requires the library code itself to fire such a notification is unacceptable (as is any approach that requires the server to append such notification code to library source).

It's been several months since I last worked on this problem. I think the SCRIPT element does not support a loaded/complete property as does IMG. This means that using referenced script elements (i.e, the "src" attribute) may not be an option. Creating SCRIPT elements with inline JS code retrieved from an XHR (a trivial change to current code) appears to work in non-IE browsers. (Well, chrome and FF 3.0.4 on my Linux machine, and the latest Safari on the Mac...and it did not work in IE8 on Win7).