Randy said:
I have yet to see an advantage to using eval over dynamic insertion. The
one place I might worry about it would be in IE4 and that falls way
outside the boundaries of "common and modern" browsers.
The only windows based browser where they are even close is in IE. FF2,
FF1.5, Opera9 and Safari3, the eval call took almost twice as long as
dynamic script insertion. I used a very simple test case and I think I
actually know why the results are what they are. I am, by no means, an
expert on how eval calls are done inside a browser. From what I have
read, and my own thoughts, it seems that eval is opening and using a
second script engine whereas dynamic insertion is using the currently
running engine. That could be true, it could be patently false though.
It might explain the time differences where that is the time to load the
second JS engine.
IE7 was consistently giving me ~2600 milliseconds for both calls.
FF2.0 eval was ~1900, dynamic insertion was ~750ms.
Opera 9 eval was ~600, dynamic insertion was ~350ms.
Safari3 eval ~300, dynamic insertion was ~150ms.
The test code is at the bottom of this post.
This test is not right. What are you really measuring?
The test is broken and the logic is flawed.
Broken because of this bug: In the DOM test, you take a string
containing javascript code and use that as src of a javascript tag. That
will never work. If you had appended the script element to the head, you
would have seen a javascript error as a result.
Flawed because with eval you take a pice of javascript code, insert it
into the document, run it and measure the total time of all this,
including execution. So far all good. But the DOM test just makes a
"dummy" element with a faulty src and then do nothing more with it. You
don't run any code. You don't insert the element into the document. You
just measure the time it takes to create a faulty script element. That's
it. So of course that will be fast.
A suggestion for a better test:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Eval vs DOM test</title>
<script type="text/javascript">
function testIt(){
var stringToInsertEval = "document.getElementById('divEval')"+
".innerHTML='new Text '+i;";
var stringToInsertDOM = "document.getElementById('divDOM')"+
".innerHTML='new Text '+i;";
var beginEval = new Date().getTime();
for (i=0;i<10000;i++){eval(stringToInsertEval)}
var endEval = new Date().getTime();
var beginDOM = new Date().getTime();
var head = document.getElementsByTagName('head')[0];
for (i=0;i<10000;i++){
var newScript = document.createElement('script');
newScript.type = "text/javascript";
newScript.text = stringToInsertDOM;
head.appendChild(newScript);
}
var endDOM = new Date().getTime();
dynamicTotalTime = endDOM - beginDOM;
evalTotalTime = endEval - beginEval;
document.getElementById('results').innerHTML = 'eval took ' +
evalTotalTime + ' milliseconds.<br>Dynamic Insertion took ' +
dynamicTotalTime + ' milliseconds.';
};
window.onload = testIt;
</script>
</head>
<body>
Eval: <span id="divEval"></span><br>
DOM: <span id="divDOM"></span><br>
<div id="results"></div>
</body>
</html>
This test (as well as your own test?) asumes that the javascript that we
want to insert has already been fetched and is contained in a variable.
We could also make another test where the eval test includes fetching
the javascript to be included via Ajax and where the DOM test fetches
the javascript the traditional way by setting the src attribute of a
script tag. But I think that's not really what this test was all about.
Now, when you run this test, you will see totally different numbers, in
favour of eval().
My results where:
IE7 eval was ~3469ms, dynamic insertion was 15797ms.
Opera9 was ~812ms, dynamic insertion was ~2563ms.
FF2.0 eval was ~2922ms, dynamic insertion was ~4547ms.
Safari3 eval was ~422ms, dynamic insertion was ~703ms.
MB