Nik said:
Adding 2000 elements to the page outside an event handler takes a handful
of milliseconds. Doing the same from within an event handler takes over 6
seconds. Doesn't happen in Chrome, Opera, Safari or even IE.
Does anyone else see this with Firefox 3.5.5 or is it just something weird
happening on my computer? I thought it might be some flaky addon, so
tried it with a fresh Firefox profile, same result.
Demo:
http://nrkn.com/temp/ffwtf/
"Outside event handler: 99ms
Inside event handler: 11050ms"
in Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.5) Gecko/20091123
Iceweasel/3.5.5 (like Firefox/3.5.5; Debian-3.5.5-1) GTB5
("GTB" apparently means Google ToolBar but I have a lot of other add-ons
installed, too.)
But: Your analysis of the situation is wrong, and your test case is flawed.
0. There is no "page". The test case uses an (invalid) HTML document.
It must be considered invalid HTML because there is no public
standard that specifies its current HTML-resembling markup.
As a result, since there is not at least one implementation of it that
implements each feature (which is an exit criterion for a W3C Working
Draft to become a W3C Proposed Recommendation), it is more then likely
that different implementations exhibit different behavior already just
because of their different level of support for this non-standard markup.
Consequently, for the time being, Web development test cases should be
Valid HTML 4.01 (the newest Specification with Recommendation status)
unless a specific markup language and its DOM is being tested.
1. It is incorrect of you to say "inside event handler" and "outside event
handler" for two reasons:
1. The code in which you are using `innerHTML' is event _listener_-code.
(The built-in unmutable event handler of the DOM implementation calls
it.)
2. Where you display "outside event handler" is actually *within*
the event listener for the `load' event of the `body' element.
2. `test' is particularly bad an identifier for a property of the global
object, especially if there is an element with ID `test' in the test
document.
Remember that testing frameworks may introduce such a method that would
be overwritten, and that IDs of elements become the names of properties
of a host object in the scope chain in MSHTML/IE and potentially other
runtime environments that support this referencing.
3. You are missing here that non-standard implementations like that of
MSHTML do not pass a reference to an event object to an event listener.
As a result, for those environments you are displaying the wrong text
(according to your wrong definition, though) because `e' is either `null'
or (being `undefined' in my tests with MSIE 6.0 on Wine) converts to 0,
the same as `null' does. (See the ECMAScript Language Specification,
Edition 5, 11.9.3, steps 3, 8 and 9, and Edition 3 Final which
corresponds more with the tested environment but says the same.)
4. *Most important*: You are missing here that the initial situation for the
second test is not the same as for the first test.
Because in the first test the `div' element with ID `test' did not have
any children before the assignment to `innerHTML', while in the second
test it did have 2000 SPAN children each with one text node child that
need to be removed first.
That need for removal, potential marking for garbage collection or
effective garbage collection of host objects no longer being referred to,
and re-addition would explain the greater time it takes very well, much
better than your (provably wrong) notion of "outside" and "inside".
The differences between runtime environments that you observed could then
be easily attributed to a more sophisticated comparison algorithm in the
`innerHTML' setter (that would not remove and re-add if the content is
the same), and garbage collection using other parameters, in at least
one of these environments. As for the former, it would be worth to take
a look at the source code of the respective implementation; as for the
latter, it would be worth to take a look at the size of the memory
footprint of the user agent before and after the test.
Bottom line: Be sure what you are testing before complaining, and avoid the
proprietary `innerHTML' property (as if that was news around here).
F'up2 comp.lang.javascript;
please do not crosspost to alt.* and Usenet without.
PointedEars