
Faster than jQuery(document).ready() - Wait Until Exists - AltIvan
http://javascriptisawesome.blogspot.com/2011/07/faster-than-jquerydocumentready-wait.html
======
spjwebster
DOMNodeInserted is deprecated in the DOM Level 3 Events recommendation, along
with all the other mutation events:

[http://www.w3.org/TR/DOM-Level-3-Events/#event-type-
DOMNodeI...](http://www.w3.org/TR/DOM-Level-3-Events/#event-type-
DOMNodeInserted)

They have been deprecated because they perform poorly:

> Firefox, for example, when it realizes that a mutation event has been turned
> on, instantly goes into an incredibly-slow code path where it has to fire
> events at every single DOM modification. This means that doing something
> like .innerHTML = "foo" where it wipes out 1000 elements would fire, at
> least 1000 + 1 events (1000 removal events, 1 addition event).

[http://lists.w3.org/Archives/Public/www-
dom/2009AprJun/0072....](http://lists.w3.org/Archives/Public/www-
dom/2009AprJun/0072.html)

> Mutation Events are widely acknowledged as “slow” in terms of the real
> performance degradation that occurs on websites that use them heavily for
> tracking changes to the DOM

<http://www.w3.org/2008/webapps/wiki/MutationReplacement>

~~~
mrspeaker
The spec says "A new specification is under development with the aim of
addressing the use cases that mutation events solves, but in more performant
manner." so hopefully it won't be too hard to port things like this over... I
hope so anyway, because the mutation events are mighty handy!

------
cstuder
You know how you can accelerate your page even further?

Don't use 1.49mb large GIF animations as background images...

~~~
latch
this is why we need vote counts to be displayed again.

~~~
julian37
I'm all for bringing back vote counts, I do sorely miss them... but I have to
ask, in this particular case, how would mankind be served if we knew that 127
more people agree with cstuder? Maybe I'm missing something, this is an honest
question.

~~~
speckledjim
If people saw [ 528 ] as the vote count for that comment, they'd be less
likely to upvote it themselves.

~~~
sethg
That would be a bug, not a feature.

If you see a comment or article you approve of, you should upvote it,
regardless of how popular (or not) it is among other people. If there are 529
people who approve of a certain comment, then it comes by those 529 upvotes
honestly.

~~~
speckledjim
This is the reason why some beggars on the street make more money than a full
time job (If they're in a really good spot).

Everyone thinks they're just giving them a little bit. But all those little
bits add up to a lot. Without any visibility into how much other people have
already given them, there is no way for people decide if they really _need_
the money or not.

If you saw a beggar on the street, and knew that they'd already been given
$1000 so far that day, would you still give them a dollar?

~~~
sethg
I don’t see upvoting as giving something to a beggar; I see it as an exchange
of value. You give me something I like (something interesting to read) and I
give you something you like (karma).

------
mathias
Why are you comparing this to `jQuery(document).ready()`? Apples and oranges.

You say it’s faster, but fail to provide any numbers / a jsPerf test case. I’m
sure it’s faster to execute `waituntilexists()` _initially_ , but if you take
into account it uses an 5ms interval in which it traverses the DOM for the
same elements over and over again until they’re finally found, it seems it
probably has a negative impact on performance overall.

What’s wrong with event delegation anyway?

~~~
AltIvan
OP here. The 5ms interval is only used on old versions of Internet Explorer.

It uses getElementById to traverse the DOM and it is said to be the faster
selector in javascript.

------
tszming
The polling approach is already used in the YUI2' onAvailable method.
<http://yui.yahooapis.com/2.9.0/build/event/event.js>

But your code should be faster -because you are polling at the 5ms interval!

~~~
adamdecaf
Which may not even be every 5ms...

------
Jencha
"it's faster" - but where are the numbers?

~~~
locci
I think he meant faster as in executed before, rather than in executed faster.

~~~
julian37
Still doesn't answer the question: how much earlier is it executed? I would
like to know.

~~~
locci
actually, the script doesn't make any sense because it would be executed as
soon as the browser is idling, that is after it has rendered the dom
completely, that is when the DOMContentLoaded event fires. The right way to
run a script right after an element has been created is to place the script
right after the element closing tag.

You still can use it for setting late binding event handlers though.

~~~
Encosia
It's using DOMNodeInserted (when available), which does fire as each element
is created.

------
NathanKP
I like the idea and it does seem that it could reduce the time that your
JavaScript code has to wait before it can run. However, in reality most real
JavaScript front end code frameworks require not just one element but multiple
elements, and nested elements. I would be hesitant to start running JavaScript
just because one element was ready unless I was sure that other elements that
my code referenced or manipulated were also ready. I'm sure it would be
possible to make a version that allowed you to specify a list of elements to
wait for before running code, but then that creates a nightmare for code
maintenance, keeping track of the entire list of elements that your JavaScript
requires. For me the jQuery(document).ready() method seems easier and more
reliable.

------
biot
Given that you're releasing this as open source, why not put it into a GitHub
account instead of Pastebin?

------
valisystem
Quick remarks :

* I could test it myself, but I expected to have in the article detailed information on the different possible states the document can have when my callback is called. The questions I know the answer when waiting for the whole document to be loaded : Is it half loaded ? What is the DOM state ? Is completely loaded ? If not, have the document JavaScript code been entirely ran ? and so on. This kind of question left unanswered often lead to hard bites.

* why using "itself" ? I would have used a "sensible default" : when no context is given, use the waited DOM object instead of an arbitrary value (document), and use something else when it is explicitly given. The "itself" thing should be left as an internal flag IMHO.

~~~
AltIvan
1) The dom state is that everything inside the HTML element that you were
waiting for already exists when the function is executed.

2) When i am writing javascript is very common for me to use the global object
(window) as the context; so in my case is not a good idea to use the HTML
element as context by default.

------
dmethvin
Does someone have a really good example of where this would be useful? The
description is basically, "When this element exists, do something" but what is
the something you'd do? If it's styling, that should be done in CSS. If it's
event handlers, that can be done with `.live()` or `.delegate()`.

I'd also like to see some benchmarks to back up the assertion that this is
faster. The DOM modification events are generally accepted as slow and it
seems like this is leaving a handler attached for the duration of the page's
existence.

~~~
flamingbuffalo
some UI stuff could benefit from this: things like turning a list into an
accordion. (Normally there is at least a little work to be done to ensure you
don't get a flash of unstyled/unscripted content, if this fires fast enough
you could avoid that)

------
acangiano
Something like this should be built-in in jQuery.

You can do $(document).ready(), why not, the admittedly syntax sugared,
$("div#main").ready().

~~~
jterenzio
I created a plugin for this type of thing a while back too:

<http://plugins.jquery.com/project/available>

------
ck2
Very clever.

I'd like to know if there is any performance hit though, NodeInserted fires on
basically on every single fraction of page creation.

~~~
AltIvan
That is why it only uses getElementById to traverse the DOM.

------
dawjan
This script is amazing i use for load cufon i try

/ _Cufon.DOM.ready(function() {_ / / _$(window).load(function () {_ / /
_$(document).ready(function() {_ / / _Cufon.DOM.ready(function() {_ /

And now is 40% faster

