I am using JQuery to append large amounts of text inside a tag. I find the more text currently within the tag the slower appending is, and for large amounts of text it is too slow.
Is there a more efficient way to append text? Such as for instance creating dummy child tags and setting the content of them rather than appending to the parent?
I am using JQuery to append large amounts of text inside a tag. I find the more text currently within the tag the slower appending is, and for large amounts of text it is too slow.
Is there a more efficient way to append text? Such as for instance creating dummy child tags and setting the content of them rather than appending to the parent?
Share Improve this question asked Jan 25, 2010 at 5:51 hojuhoju 29.5k39 gold badges137 silver badges178 bronze badges 4- are you certain the bottleneck is the actual DOM manipulation and not to time to manufacture the content you're inserting? – Scott Evernden Commented Jan 25, 2010 at 6:23
- yep - I tested with and without appending – hoju Commented Jan 25, 2010 at 10:57
- Is the content in a table (either directly in a TD or indirectly somewhere up the parent chain), or other non-fixed-size element? Every time you manipulate the dom, a recalculation of positioning is required. The effect is more noticeable in tables and elements without fixed sizes. – Graza Commented Jan 25, 2010 at 14:53
- it is all DIV structured, but that is an interesting idea. If correct then there is not really a way around this delay... – hoju Commented Jan 26, 2010 at 0:50
4 Answers
Reset to default 6Check this presentation and this one too: jQuery Anti-Patterns
And in general:
- do not .append() in loop
- do not append directly into DOM
- build a string and than append it or use DocumentFragment
- do not append directly into DOM
Use DOM DocumentFragments to append a bunch a node, and take a look on Nicholas Zakas presentation in slideshare "writing-efficient-javascript"
As I have been testing my site, I have noticed that .innerHTML
is far quicker than jQuery's append methods. This is deprecated though and support may dwindle and die in future browsers. That said the bgcolor
attribute still works and I remember being told that was being deprecated about a decade ago. Don't append scripts with the html fragment either as they need eval'ing (jQuery appears to do this automatically leading to slow times whereas with innerHTML
you have to do it manually if needed). Eval is dead slow don't use it if possible. Again as previously mentioned joining an array is more efficient than string concatenation. Use variables to point to DOM nodes (i.e. var this = document.getElementById("YourDomNode")
then work with this
where needed instead of repeating the document.getElementById
statement). Declaring variables outside of a function allows them to be accessible from any function. Please note this is client side script so the variable value is a unique reference for each user. Doing that highly repeated strings can reduce file sizes depending what your doing. If you absolutely have to load in your JavaScript inline as part of your html fragments try this:
/* Call this section after appending to the dom with innerHTML */
var f = function() {runScripts(document.getElementById('newDOM_Section'));};
setTimeout(f,1);
/* Stick the following in your main .js file */
var stringScript
var f
function runScripts(element) {
var scripts = element.getElementsByTagName("script");
var intScriptsCount = scripts.length
for (var i = 0; i < intScriptsCount; i++) {
stringScript = scripts[i].text
setTimeout(stringScript, 1);
}
}
The above code will make the DOM changes visible before all the scripts are eval'd. This isn't multi-threading though so be careful of its use. Far better to use attributes for event handlers (onclick, onchange etc.)
Finally before manipulating an element in the dom set the style to display:none, manipulate it then set the style back to display:inline (inline is default for some mon elements) or wahtever it was previously.
This is just a quick mental dump of some tactics ive used so any input / derision of bad practice is wele.
Instead of appending multiple times, store each string in array and join the array when you append it to.