Accessing DOM elements with JavaScript is slow so in order to have a more responsive page, we have to do the following things
Cache references to accessed elements
Update nodes "offline" and then add them to the tree
Avoid fixing layout with JavaScript
Can anyone tell me how to do the first two things?
Thank You
These are some abstract questions, ones even that do not necessarily relate to each other.
1. Cache references to accessed elements
Caching references is a practice and sometimes a necessity. The act of maintaining a reference to an element locally (or, um, globally) is rather simple. When working with DOM methods like
document.createElement()
, there's usually a variable it's saved to. This is a reference that may be cached for later use.document.getElementById
returns a reference to an element,document.getElementsByTagName
returns a list of references, as doesdocument.querySelectorAll
, etc.2. Update nodes "offline" and then add them to the tree
When you say "offline", I'm not quite sure the context you're referencing. Is this before whatever element (including a string like
<div>
) is added to the DOM?There are three primary ways to interact with elements:
document.createElement
(withelem.appendChild
)There was a day in the somewhat distant past when this was the de rigueur way of monkeying with your page content. It appealed to the subset of the "web developer" community which was comfortable with an API-like, programmatic way of addressing and manhandling the DOM and it's denizens; it almost looked like real code, the hard stuff.
Sure, some of the code kinda rambled, and iteratively creating and appending and appending to those and on and on looked wicked-cool to anyone who didn't have to birth it.
If you were clever with
cloneNode
, you could get more reasonable results with DOM nodes. But I think until the last few years,cloneNode
wasn't a great option. I may misremember that, cargo-cult and all. Correct me if I'm wrong.Then IE came along and gave us...
elem.innerHTML
Surprise! This was non-standard, man. How could they? The only problem was, it was really fast. Killer-fast (like IE6/7 never happened either, we all want to forget).
DOM was... whatever, browsers were slow and inefficient and weren't really running real code anyways, so DOM's slowness was tolerated. But then, for whatever reason,
innerHTML
entered stage-left and groovy, dude, it was faster than DOM methods. And elegant, in "I like staring at markup instead of DOM methods all day" way.Eventually, everyone got on the
.innerHTML
bandwagon, and it's now a de facto standard. It's fast, right?Well. Depends. Doing
elem.innerHTML = "<p>Hey!</p>"
was fast, yep. So waselem.innerHTML = '<p>Hey!</p><p>Yo!</p><p>What!</p>'
. So naturally folks thought, it's a property, let's get giggy andPsuedo-code there. Where's the problem?
+=
is like kryptonite to our sprinty friend,innerHTML
. Crazy-bad, never-do-it, don't-even-think-about-it bad idea. Why? AFAIK, it has to do with the manner in which.innerHTML
assaults the inner content, so when youelem.innerHTML += '...mayhem...'
, you're "tearing down" the DOM each time. Or something. Which makes the DOM weep.Don't make the DOM cry.
documentFragment
So then at some point (has it always been there? DOM Level 3, if that means anything),
documentFragment
crashed the scene. MDN's brief note about it sums it up, though. It's aNode
separate from the main DOM. Like a little box you put stuff in, before moving it to the daddy DOM.In terms of speed, it's right behind
.innerHTML
for the most part, and is all DOM-programmy and stuff. Nifty.In terms of caching, much of that has to do with how you structure your code and use scope to your advantage. Take for example:
http://jsfiddle.net/userdude/T6YLZ/
I keep the
target
andsource
above theclick
handler's scope, so that when I access them later, I already have them. Since I don't add thewords
tosource
untilwindow.onload
, I won't get all of thespan
elements with thewords
to move totarget
untilsource.click
occurs.You seem to be describing
documentFragment
s in your terminology. And they're cool. I've only recently come across them, although apparently for those in the know they seem to have been there for a couple years or more. So if you're one of thosemust.use.dom.methods(now)
, usedocumentFragment
s before inserting into the non-fragment DOM.However... Keep in mind there are times you will use
elemn.innerHTML
, because you're adding markup. Maybe you have templates, AJAX response markup, whatnot.Just don't
+=
whenelem.innerHTML
ing.