[jQuery] Attn. developers. Speed of getElementById
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
The original is in Russian:
<a class="moz-txt-link-freetext" href="http://blogs.gotdotnet.ru/personal/poigraem/PermaLink.aspx?guid=88FECDF4-739C-46C0-8496-589EFD553B60">http://blogs.gotdotnet.ru/personal/poigraem/PermaLink.aspx?guid=88FECDF4-739C-46C0-8496-589EFD553B60</a>
Here's a quick translation:
------------------------
We've hit a problem where getElementById is working slowly on a _very_
large page
After some research we've found out some interesting facts
- Speed of getElementById depends on the length of ids. Tests have
shown that for two identical documents, one with ids like aXXXX,
another with ids like ааааааааааааааааааааааааааааааааХХХХ, the speed
of getElementById would differ by a factor of two. This is especially
important for ASP.NET pages which usually have long ids
- There are fast methods and slow methods:
-- Fast
---- parentNode
---- nextSibling
---- ownerDocument
---- firstChild
-- Slow
---- previousSibling
---- getElementById
---- lastChild
The getElemenByTagName has a paradox. It returns the list of elements
very quickly. However, access to elements from that list is very slow.
It feels as if it were returning a proxy of sorts.
In a large tree it's faster to collect a hash of all element ids than
use getElementById. This may look like this:
[code]
<pre
style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span
style="color: rgb(0, 0, 255);">function</span> build_document_id_map()
{
<span style="color: rgb(0, 0, 255);">var</span> r = document;
map = {}
build_id_map( r, map )
<span style="color: rgb(0, 0, 255);">return</span> map
}
<span style="color: rgb(0, 0, 255);">function</span> build_id_map( node, map )
{
<span style="color: rgb(0, 0, 255);">for</span> ( <span
style="color: rgb(0, 0, 255);">var</span> e = node.firstChild; e != <span
style="color: rgb(0, 0, 255);">null</span>; e = e.nextSibling )
{
<span style="color: rgb(0, 0, 255);">if</span> ( e.id ) map[ e.id ] = e;
<span style="color: rgb(0, 0, 255);">if</span> (e.firstChild ) build_id_map( e, map )
}
}
<span style="color: rgb(0, 0, 255);">var</span> cache;
<span style="color: rgb(0, 0, 255);">function</span> get_element_by_id( id )
{
<span style="color: rgb(0, 0, 255);">if</span> ( !cache )
cache = build_document_id_map(id)
<span style="color: rgb(0, 0, 255);">return</span> cache[id];
}</pre>
[/code]
To test this, you may use the test I