The hardest obstacle to overcome with JavaScript is deciding the best way to make the page change dynamically. There has always been a debate hovering around innerHTML and document.createElement. Jonathan Snook just questioned it again, and it reminded me of some ideas I’ve been meaning to talk about.
So, I have been doing some heavy JavaScript work lately with the intent of making a web page behave as desktop like as possible. This involved frequent, large changes to the DOM. Originally, the entire app was built using document.createElement. Everything worked, but it was slow. Out of curiosity, I rewrote one section with innerHTML, and that section began operating at warp speed.
Multiple tests later, and the entire application was rewritten to use innerHTML. The change resulted in a more responsive application. That was the only major benefit. On the downside, the code was arguably harder to read, while document.createElement allowed the code to still feel structured. But our users come first, and the speed increase was too much to pass up.
We brainstormed different ways of cleaning up the code, and came up with a few ideas. The first two, XSLT and JSONT, were shot down because of the amount of rework they would require, so we went with a third option. Basically, just create all of the markup in the page, and slap on a class name of ‘hide’ to anything you don’t want to show. Then, with JavaScript add and remove hide as needed, and just change the values of nodes. This resulted in a more significant speed increase over innerHTML, and it is what we will be going with until we find something better.
Interesting problem Ryan. I am sure all of us face this. Yes, innerHTML is freakin fast. Check out PPK’s tests here: http://www.quirksmode.org/dom/innerhtml.html
It would help if you could give an example of what you are trying to explain. Did “add & remove hide” mean “show / hide” or add/remove? Since they are already in the page, won’t the page size grow? The advantage of they being in javascript is that they are cacheable (so isn’t innerHTML preferable).
Thanks, Mandy. http://mandysingh.blogspot.com
You might be interested in the post Jeremy Keith put up on the Buzz a few hours ago… a link to a script called DOM Builder by Dan Webb.
http://www.webstandards.org/2006/04/13/dom-builder/
It may be what you’re looking for.
I could be an adept of the hide/show method because it’s a little bit mor like a real windows application : most of the interface stuff and ressources is loaded at the beginning and once. It may be longer to load, but it’s sure you gain a lot of speed afterward.
After looking at the DomBuilder code, I found the Base object wich seems to be really nice for the OOP in Javascript. You should have a look at it. Also, the DomBuilder author says it’s even better at modifying the DOM than it’s own script.
Here it is : http://dean.edwards.name/weblog/2006/03/base/
You may be interested in this version of Dom Builder or domEl
Benchmarking this functions shuld be very interesting.
The problem isn’t in the time developing the createElement code, it’s creating and appending those nodes into the document. Dom Builder and domEl are only wrappers around this method and will still be slower than innerHTML.
Man I was just wrestling with this very question this morning, trying to decide which route would be the best. I had actually determined to try to do just as you describe. i.e. send all the bits down the pipe and show/hide as needed. Very cool to hear your real work experience drew the same conclusion. Thanks for the insight.
As Jonathan said, it is not the development time that bothers me. It is how slow the page performs when the user is interacting with it.
Mandy - The growth in page size was easily worth the speed increase it provided. Since the pages I’m building are only loaded once, but can be manipulated without the need for another refresh for hours, I was more concerned with keeping up the speed for the hours, and not just the initial load.
Carson - Give it a try. I haven’t come across anything faster. On top of that, Kevin go jump into the page and edit the markup normally, without having to look at JavaScript. It is pretty nice.
I really think this is the best approach for a project involving both programmers and designers, too. As you said, someone can edit the HTML and CSS without having to parse through the JavaScript, and the programmer can edit the JavaScript without worrying about the content (as much).
You can even seperate the user interface from the actual text and content. The strings could be defined as a set of divs with ids, and the dialogs could copy the innerHTML over from the strings div into the appropriate dialog (much like strings resources in Windows). It makes internationalization a lot easier, too.
Yes yes yes yes yes! I couldn’t agree more that it’s not necessarily the development that we’re worried about. First off, I can’t believe I’m sitting here yet again typing about innerHTML vs DOM methods. As for Jeremy Keith, I’m done giving him crap on the matter, and I don’t want to lose a good friend over some stupid debate (not to mention we probably share the same feelings anyway). The most important matter is that indeed, users come first. Developing with Standards is one thing. And for the most part, that always works. But when it comes to hindering the users experience… then innerHTML it is. Not to mention it’s supported by the same browsers (if not more) than those of which support DOM methods to createElement and appendChild. And yea, as Ryan said, it “feels more structured” but really, that’s just from a code perspective again. It all ends up being the same thing in the end.
Doesn’t sound too accessible to me to have hidden chunks of markup that may not always be shown. Think of a screen reader user having to listen to pointless crap. I have seen that happen and it is terribly frustrating, confusing, and even disorienting for some blind people.
Interestingly, some screen readers will observe display:none, while others will not.
Hence, I’d say do with care, figure out a fourth way, or maybe try that DOM Builder which I just recently read about as well!
Anup: one thing I’ve been doing is creating HTML shells on the page that have no content (therefore, screenreaders wouldn’t hear or have any issues) and simply populating them via JavaScript/AJAX as need be.
Dustin wrote: “As for Jeremy Keith, I’m done giving him crap on the matter, and I don’t want to lose a good friend over some stupid debate”
Dustin, you gave me crap because you (incorrectly) thought that I was favouring DOM methods over innerHTML. In fact, all I did was compare the pros and cons of both without declaring either to be superior or inferior.
Please read what I wrote and stop misrepresenting my position on this… because I haven’t got one; I’m quite happy sitting on the fence.
Hah. I never realized that innerHTML was that much faster. That makes me feel good for using it, when in the past I had just considered a lazy habit.
But yeah, really consider XSLT next time. It makes the code so much easier to work with and it is incredibly fast with large XML documents.
The project that I’m working on right now is relatively large. Its a survey system to be used within a rather large international company to survey their plants and offices around the world, regarding productivity and efficiency. I have dozens of XSL files for this… some with just a few lines in them. But it makes the JS so much easier to read… and much smaller. I did the first version without XSLT and ended up with 1000 line+ JS files. The latest version however has JS files with no more than 350 lines each in them.
Very nice. :)
Maybe somthing like AHAH (http://microformats.org/wiki/rest/ahah) would work better here?
I cant really speak to the argument that innerHTML is faster, but I can argue for the use of document.createElement. In my experience with relay.statsinsight.com, it really came down to using createElement exclusively because of my heavy use of Objects. For example, I made a class for a Directory and inside it, created a method to generate a visual element. If you use innerHTML in this case, the element has no logical connection to the object, but when you use createElement you automatically get a direct link to the element as an object. This saves you having to give each element an ID then using getElementById to use it. I could simply do a line of code in the class like
this.icon = document.createElement('img');
and from then on i could access that icon bydirectory.icon
… simple and effective when you start getting complicated in your app design.Blaise: I didn’t say that Base.js is better at manipulating the DOM that DOMBuilder, I said it was better than the OO solution I have. Base.js an OO wrapper - its got nothing to do with the DOM. It’s great at what it does do.
innerHTML is much faster but the big difference is only really on IE. It does have large disadvantages though and is obviously not the most elegant way of implementing DOM manipulation as an API. Shoving strings around just seems wrong to me. Thing is though is that IE happens to be faster with innerHTML and until that’s not the case we are stuck with it. I don’t think its the best way - it’s just the way that works best at the moment.
çiçek gönderirken cicekclub a reklam verirken e-reklamix e gidin
Jeremy Keith said: innerHTML is faster, but “heavy-handed” and “sledgehammer”, that doesn’t mean it’s bad! that might sound negative but what I’m striving for is accuracy… innerHTML is fast, easy, proprietary and heavy-handed… DOM methods are slower, long-winded, standardized and precise… Now, which technology have I described with a negative spin? The answer to that question is entirely subjective and depends on where your particular priorities lie!? Please read what I wrote and stop misrepresenting my position on this… because I haven’t got one!
Yeah, right!
Everyone needs a hug.
I know why! appendChild does a request to check if the document is still correct, and more! In IE does every time, in FF just once!
DomAxh (http://domaxh.sourceforge.net) converts XMLHTTPResponse objects into (X)HTML DOM, reducing the need for innerHTML (of course, it’s not as fast as innerHTML) when working with AJAX (AHAH or whatever)