10

I wanted to see different views / opinions on this.

I've got Jquery invoking a function through ajax. It loads data two ways:

  1. The ajax script loads JSON data from the same server, then uses JS to parse it and append it into html.

  2. The ajax script loads complete html / script set up directly via that php script that's called and then JS appends it to html div.

I'd assume #1 is faster since it's loading a basic JSON array then uses JS to parse it and append to html.

Opinions?

Thanks!

Michael Mikhjian
  • 2,760
  • 4
  • 36
  • 51

6 Answers6

12

There are a lot of variables. #1 may be faster, provided that your JavaScript isn't assembling the result piecemeal and assuming that the data is markedly smaller than the equivalent markup. If you're assembling the result piecemeal, or if the data isn't much smaller than the markup, it may well be slower. It also depends on the speed of the user's network connection vs. the speed of their CPU and browser (Chrome is fairly fast, IE7 is fairly slow), etc.

On the piecemeal thing: For instance, if you're loading a 200-row table, and you're building up the rows like this:

// ...stuff that initializes `tableBody` and clears out old stuff...
for (index = 0; index < stuff.length; ++index) {
    tr = $("tr");
    tr.append("td").html(stuff[i].a);
    tr.append("td").html(stuff[i].b);
    tr.append("td").html(stuff[i].c);
    tableBody.append(tr);
}

...then that's probably going to be fairly slow compared with how the browser would blaze through the equivalent markup.

If, however, you're doing it more like this:

markup = [];
for (index = 0; index < stuff.length; ++index) {
    markup.push("<tr>");
    markup.push("<td>" + stuff[i].a + "</td>");
    markup.push("<td>" + stuff[i].b + "</td>");
    markup.push("<td>" + stuff[i].c + "</td>");
    markup.push("</tr>");
}
tableBody.append(markup.join(""));

...you're in better shape, because there you're getting maximum reuse out of the browser's ability to parse HTML quickly (which is, fundamentally, what browsers do, and what they're optimized for).

It can seem, on first glance, a bit counter-intuitive that building up a string and then handing it to the browser can be faster (even markedly faster) than building up the structure directly with DOM methods or jQuery. But the more you think about it, the more obvious it is (and yes, I have tested it) why that's the case. The DOM is an abstraction that the browser has to map to its internal structures, and each call you make to a DOM method crosses a boundary layer between JavaScript and the browser's DOM engine. In contrast, adding to an array is fast, join is fast (even string concat is fast on modern browsers). Handing the browser a complete string keeps trips between layers at a minimum and lets the browser build up its internal structures directly without worrying about their DOM equivalents (until/unless you ask for them later). The last time I tested this was a couple of years ago, and the results were dramatic. I should try it again with current browsers; no time today, though...

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • It's a 10-row output. So it's very basic. In fact, I initally had it set up the 2nd way you provide, but I changed to the first, thinking it was faster. I guess I'll need to experiment; if the difference is <100ms then no need to mess around with it. – Michael Mikhjian Mar 12 '11 at 13:39
  • 1
    @Michael: If it's 10 rows, let's just say there'd have to be a **lot** of columns or very, very complicated structures involved for you to notice a difference. :-) – T.J. Crowder Mar 12 '11 at 13:44
  • How does this compare to building the exact DOM object in memory? markup = $("
    "); with .append() to "markup" and then append to the actual DOM?
    – iivel Mar 12 '11 at 14:46
  • @iivel: I'm sorry, I don't understand the things you're asking me to compare. – T.J. Crowder Mar 12 '11 at 14:52
  • @T.J. - I'm wondering if there is a noticable performance difference in pushing a string into an array, vs. building a DOM object in memory. I'll have to JSFiddle something up when I get time if you haven't tested that. – iivel Mar 12 '11 at 15:05
  • @TJ - Made a couple fiddles. String concantonation appears faster than native jQuery in memory objects. Needs more testing I think, but I was suprised. Beware, it takes a few sec for each to run (needed 10k rows to find any noticeable difference) http://jsfiddle.net/iivel/J8UQU/ http://jsfiddle.net/iivel/vngfj/ Definately worth an upvote! – iivel Mar 12 '11 at 15:18
  • @iivel: As I said above, I *had* tested that, a couple of years ago, and found that it was markedly faster (esp. on IE) to build up the string and then hand it over. There are actually four things to compare, I'll do it when I get a chance: Using an array, but doing a bit of string concat so you're not constantly pushing tiny strings on the array; using an array but never doing string concat (lots of little strings); using the DOM API, building up the stuff in a DocumentFragment and then adding it (to avoid repeated reflows); using the DOM API without a fragment. – T.J. Crowder Mar 12 '11 at 15:40
  • @T.J. --- thanks for the input. I ran a number of tests and the string concat within the array (using join) is definately the fastest. As a note, it is a bit quicker yet if you wrap everything in a parent element. Last fiddle: http://jsfiddle.net/iivel/RUJgr/ – iivel Mar 14 '11 at 18:15
3

Saying which one of those two solutions is faster is not possible : it all depends on what you are doing, be it on the PHP side, or on the JS side.


What you should consider, mainly, is how difficult developing those solutions can be -- and if it means duplicating some efforts :

  • PHP runs on your server ; you control the environment ; and don't have to adapt your code for each kind of browser there is
  • If you display some stuff using Ajax, chances are you might want to display those using non-Ajax, too -- which means you might already have some PHP code to render that ; if that's the case, duplicating it in JS might require more work that just re-use it.


Doing things on your server means :

  • Probably a bit more network usage : sending HTML instead of data can mean a bigger payload -- but using compression, this shouldn't make such a big difference.
  • A bit more load on your server (you could cache some stuff, though) -- but rendering is generally less resource-consuming than getting the data from your database


In the end, if I can point you to the answer I gave on this question : Why is it a bad practice to return generated HTML instead of JSON? Or is it?

Community
  • 1
  • 1
Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
2

You should use document.createDocumentFragment will result in better performance. Appending to this fragment only use up memory and does not modify the DOM itself until you are ready. I believe document.createElement is still superior to innerHTML because it bypasses the string parsing. You can always run a bunch of benchmark to see the results.

Benchmark: http://jsperf.com/innertext-vs-fragment Source: https://developer.mozilla.org/en-US/docs/Web/API/document.createDocumentFragment

Tigertron
  • 628
  • 6
  • 6
1

The answer to that question depends on many factors, including:

  • Client computer speed (old machines will generally choke on complex JS parsing and calculations)
  • Network speed and the size of the generated content (this would mainly apply to big datasets that get transformed into much bigger resulting html)
  • The nature of the data manipulation the function is doing
code_burgar
  • 12,025
  • 4
  • 35
  • 53
  • Generally, on a basic data set output, Would you recommend just regular php rendering? The output that I have now is very basic; no more than 10 rows of data, each no more than 128 characters per value. – Michael Mikhjian Mar 12 '11 at 13:37
  • @Michael: That really depends. Separation of markup and data is generally a good idea, as long as cons don't outweigh the pros (see some potential issues above). Judging by your comment, you are doing something fairly trivial, so it shouldnt't hurt to reinforce good practices early on, and separate data from markup. Just my 2c :) – code_burgar Mar 12 '11 at 13:42
1

My own experience a while ago found that using innerHTML for large chunks of HTML is significantly faster than building it with document.createElement(). It's so much faster that I don't even bother writing speed tests any more. The speed difference is negligible for small, shallow structures, and for them I'll still do it with createElement() but anything more complex gets dumped in as a string.

Previously I was pretty skeptical of innerHTML, so it came as a surprise when I sat down and wrote my tests.

I'd recommend you try it yourself and write your own speed tests.

Andrew
  • 14,204
  • 15
  • 60
  • 104
1

Benchmarking will tell you what's fastest.

Robert de W
  • 316
  • 8
  • 24