Hacker News new | past | comments | ask | show | jobs | submit login
Don't wait for "DOM ready" for your app to start (plus.google.com)
126 points by jacobr on June 8, 2012 | hide | past | favorite | 39 comments



Honestly, I don't like claims like this that are offered without any support. Why shouldn't I wait for the DOM to be ready? Am I losing performance? If so, where are the benchmarks?

Frankly, I'm surprised a casual comment on G+ is getting any traction whatsoever on HN.


The DOM loaded event can take a while to fire, there's no need to wait for it but then you end up either sprinkling your html with script tags or firing a script just before the end body tag. i.e. maintenance nightmare for the former, what's the point for the latter? Neither much better than just waiting for dom loaded.

If it is taking a while to fire, better to solve that problem than piss around with a half built page in my experience. I experimented at one point with js enhancing controls just after they were declared, it's honestly not worth the effort. He'll learn.

This smacks of the bootstrap semi-colon nonsense, we all tried semi-colonless once, it ends up a nightmare, but some mistakes the next generation need to figure out themselves.


> better to solve that problem than piss around with a half built page in my experience.

Seconded. This can cause far more bugs and timing problems than it's worth. Find out what's taking so long to fire, and fix (or defer) that.


> [on placing a script before the end tag of the body element] what's the point [...]? Neither much better than just waiting for dom loaded.

I'll take sane, library-agnostic script without event listeners for $500, Alex.


Yeah, whether or not you can run stuff before DOM ready is often one of those questions where most answers are right 99% of the time and piss off your customers the other 1% of the time. Have fun debugging your little optimization when you literally can't reproduce the bug in your own debugging environment.


In my experience, the main reason is any ad content you're serving. If an ad network's content times out (which I've seen happen for hours at a time, multiple times a year), your page might take 30 seconds until it fires the DOM ready.

At one company I worked at, the ad network we used got so bad that we not only executed all our JavaScript at the bottom of every page (instead of in the DOM ready), but also only loaded the ads after that, and then dynamicaly repositioned them to the "inline" spots where they supposed to appear.


I wonder if post-loading ads is allowed in most TOSes. If I were in their shoes, I would not like it.


I agree, I also don't like claims that it impacts performance to unnecessarily wait for the CSS to download without any benchmarks. I also don't like it when people say that exponential time algorithms take longer than polynoinal time algorithms without showing benchmarks.


The supporting information was supplied with the claim. You wait for items irrelevant to your applications to (very sluggishly) load. I suggest reading the book "High performance websites", it's very thin.


At Mozilla, we were losing a few add-on download clicks because of the lag from putting the JavaScript at the bottom. So, we created a tiny bit of JS that recorded important events, which we loaded in the <head>. The queue re-fired off the events once the JavaScript loaded.

https://github.com/mozilla/zamboni/blob/master/media/js/impa...


So, the code you post requires jQuery, I am assuming, because you don't say. Which means you would need to also include jQuery in the header. Doesn't that seem like a waste? Also if you had jQuery already you could probably writing a queuing system for almost all actions, and not just "important" ones.

You should take a queue from Flickr. I took a look at how they handled this, and I think it's one the best I have seen so far.

http://dailyjs.com/2011/11/28/flickr-async/

The method there could actually be a small amount of code, and wouldn't require that you load jQuery before queuing events.


> because you don't say

Use the source, Luke!


"One should always start JS apps as early as possible and only delay operation until the "DOM is ready" that want to measure dimensions, etc. (Things relying on CSS)."

I guess the assumption here is that your script tags are placed at the end of the document - because if your scripts are placed in the <head> and they try to do things like getElementById (which does not "rely on CSS") before the DOM has been parsed, you'll definitely get an error.


You can do a lot without accessing the DOM. Assuming you have a real app, and not just a circus of jquery event handlers, then you probably have prototypes to instantiate, perhaps some models to load, etc.

The post is referring back to the old jquery advice of "put everything in $(document).ready".


This is one of the reasons YUI added the onAvailable method back in the day (2006 IIRC). See http://yuilibrary.com/yui/docs/api/classes/Event.html#method...

onAvailable lets you run a piece of JavaScript once all the nodes it requires are available. Our first iteration just checked for the existence of the node, but that turned out to be a problem if the node was large and had several sub-nodes. A second iteration checked that the node existed and had a nextSibling. This meant that the node had completed loading and parsing and the browser was now on to the next node.

This implementation naturally needed polling of the DOM, but YUI's always been pretty smart about clubbing polling events together, and not doing too much at the same time.

Combined with the fact that you only need to load the YUI bootstrap code up front and let everything else load asynchronously, this can significantly reduce download time.

I only wish YUI 2 had a better syntax that might have made it more popular. You'll have to take the word of those of us who worked at Yahoo! at the time, it was a huge improvement over YUI 1, and YUI 3 is far more JavaScript like and far less Java like.


Google avoids waiting for dom ready in webapps like gmail, and their closure library [1] doesn't have the equivalent of jquery's $(document).ready() [2].

[1] https://developers.google.com/closure/library/ [2] https://groups.google.com/group/closure-library-discuss/brow...


jQuery popularized the idea of DOM ready (which is DOMContentLoaded to the browser). DOM ready was a big improvement from what we used to do which was waiting for the onload event to fire. It turns out the majority of the stuff we do in JavaScript touches the DOM in some way and you can't read or manipulate the DOM until it's ready. If you have code that doesn't touch the DOM, then sure, you don't have to wait, but those instances are pretty rare in the real world. The big thing to keep in mind is that both CSS and JS block the DOMContentLoaded event. The best thing you can do is keep the CSS and JS that blocks your rendering to a minimum. DOM ready is usually your "perceived performance" so it's best to get there as fast as you can. Instead of trying to get your JavaScript running before on ready, you'd be better off making sure you only have 1 CSS file in your head, that your JavaScript is at the bottom of the page and other standard WPO practices.


>If you have code that doesn't touch the DOM, then sure, you don't have to wait, but those instances are pretty rare in the real world.

Bootstrapping backbone models/collections (or any other kind of data model prep) is the main use-case. A site that is mostly server-driven with some javascript ux wouldn't usually care about this technique.


Some things you could do would include firing off XHR's and creating an unattached hierarchy of DOM nodes which could then be attached once the main DOM is ready. This could be neat.


Why would you use XHR for this instead of just bootstrapping with all the DOM nodes in place. This sounds like it would slow the page down.

Twitter is just going through a complete re-arch of their front end to stop loading via XHR and says they're getting a 5x speed improvement

http://www.digitaltrends.com/social-media/twitter-kills-the-...


Normally, I am a big fan of putting everything into one HTTP response. However, if you do need to load things asynchronously, fire off as many requests as early as possible. For example, if you are showing some kind of real-time data and need to get the first batch in as quickly as possible, you might not want the complexity of two different ways of delivering the same data just to get the initial page speedup.


I was under the impression that "DOM ready" did not wait for CSS, but that "load" did. In fact, i was also under the impression that CSS (loaded in the <head> at least) blocked any further processing until it's downloaded. Am I wrong?


JS called from the head (without "async") blocks all further progress, but I don't think CSS necesarily does. (Though of course the page can't actually render to the screen without all the CSS.) SO seems to back that view up: http://stackoverflow.com/questions/4026183/as-javascript-in-... YMMV in older versions of IE. I think everything blocks with them.

I'm not sure about ready vs load, but that would make sense.


Well, "DOM ready" isn't really a thing -- but assuming we're talking "DOMContentLoaded", then you're absolutely right. It doesn't have anything to do with other resources (images or CSS) being loaded or not. It'll execute as soon as the document is parsed.

As for downloading CSS -- it won't prevent your JS from executing, but it'll block page rendering until all the stylesheets have been downloaded and parsed.


That's what I thought. Which means the original post makes very little sense- if your <script> tags are just before </body> there's surely no real delay between that an using DOMContentLoaded?


The spec agrees with you, but even MDC does not: https://developer.mozilla.org/en/DOM/DOM_event_reference/DOM...

DOMContentLoaded, in all important browsers, does block to wait for CSS. Manipulating the DOM before this event both increases the chance to make changes before first-paint (decreases "jigger" on page load) and gives you the chance to request more resources earlier.


Wow, that's a total surprise.

I guess I never really noticed this because my scripts are always included so much later in the document than my CSS.


DOMContentLoaded does not block to wait for CSS in Firefox.


> As for downloading CSS -- it won't prevent your JS from > executing,

It most surely will, in at least Gecko and WebKit. Too many pages have JS that depends on all preceding stylesheets having been loaded.


"never wait for "DOM Ready" for an application to startup"

We've linked page load times directly to lower sales funnel drop outs, I would warn against this for some people, as you will be blocking/delaying rendering of the DOM for code that is ultimately not impacting the UI

https://developers.google.com/speed/docs/best-practices/payl...


How about something like this[1]?

----

[1]: http://blog.shawndumas.com/wait-until


Hey Shawn, that's interesting. I was just thinking about a similar solution with a JS widget we're creating for our users to embed on their websites.

I have an improvement suggestion. If the client supplies their own condition, like in your example waiting for a specific element to be loaded, what about (optionally) disabling the check once onload happens?

As it is, a rogue condition check could run indefinitely.


That's a good idea.

I envisioned using it both for on-ready and for processes that might occur after page load. Sometimes widgets don't have callbacks, or for a long running template being shoved into the dom or some other such situation.

I could add a fourth (optional) boolean parameter -- stopOnReady; false ends on pageLoad, true on pageReady, and null stops on condition === true.

As to a long running check; 1.) the reason I use interval, as opposed to timeout, is that if the number of client events get heavy it will delay invoking the condition function [1]. 2.) a getElementById is native and trivial (in other words -- just don't do anything crazy in the condition function).

----

[1]: http://ejohn.org/blog/how-javascript-timers-work/


I made the discussed changes here[1]. You can run them here[2]. Thanks again for your constructive input.

---

[1]: http://blog.shawndumas.com/wait-until

[2]: http://jsfiddle.net/Pdft8/2/


I just threw up.


After having a look at this[1]. Could you explain your being nauseated? Please and thanks.

----

[1]: http://www.dustindiaz.com/smallest-domready-ever


Is there a way to achieve the same effect while keeping scripts in the <head>? (Not saying that's the best idea, just wondering.)


You could have your scripts just define functions, then call all those functions from the bottom of your <body>.

Or, using jQuery, you could probably define a custom event on the <body>, that you trigger manually from the bottom of your <body>, and have your scripts in the <head> listen for that event. I've never actually tried this, though.


YUI can poll for elements to become available, with a few workarounds for browser bugs; see http://yuilibrary.com/yui/docs/event/domready.html. I think you have to roll your own in jQuery.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: