Some Javascript/Ajax projects: “LABjs” and “mpAjax”

getify | Ajax, Misc | Monday, June 29th, 2009

The other project I released recently deals with Ajax calls, specifically with the responses to Ajax calls. mpAjax (multi-part Ajax responses) is a project aimed at making it easy to return multiple types of textual data (HTML, CSS, JSON, XML, etc) from a single Ajax request.

It is currently in the form of a jQuery plugin (although the code can and will be easily ported to other frameworks) that extends the built-in Ajax functionality to allow you to specify multiple “onsuccess” handlers, one for each “part” in a multi-part response. The format of the response is essentially corrolated to multi-part MIME email messages, whereby different “parts” are separated by a delimiter header and content-type declaration headers.

In each “part”, you can natively drop in the data/content of that type without any escaping, conversion, encoding, etc. So, HTML looks exactly like HTML and JSON looks exactly like JSON. For instance, a multi-part Ajax response might look like:

!!!!!!=_NextPart_411426488
Content-Type: text/html
<div>Hello, I'm some HTML markup, and I can use " characters natively with no problems.</div>
!!!!!!=_NextPart_2106560908
Content-Type: application/json
{"greeting":"Hello","name":"I'm JSON, natively without any transformations or escaping!"}

So, you get a nice clean separation and can return both HTML and JSON at the same time! You may ask why? I’m glad you asked. Firstly, when you try and “encode” (escape) HTML and stuff it into JSON, you add an additional \ character for every ” that is in the HTML. I’ve done some tests/benchmarks, and this can be as much as a 10% addition to your response size. Also, obviously, the server spends some time processing (with regex’s or whatever) the HTML string to escape it. I did benchmark testing with PHP’s native “json_encode()” function and saw non-trivial differences in performance when encoding an HTML block with ” characters than with the same block with instead ‘ characters.

Encoding HTML into JSON is both larger, and more processing intensive, than sending it natively. What about putting your JSON into your HTML, like inside of a text-area or hidden inputs. Same problem applies. You have to escape/encode to do that, generally, and also, you’re consumption logic on the client side is much more complex.

What are some use cases for sending back mixed-data-type responses? How about asking for some JSON data from a result set, along with a small chunk of HTML as a “template” to dump the data into? Great, clean separation of code, data, and markup. And also, you’re not sticking any markup directly into Javascript code, so your debugging and maintenance are much easier. Or, you could let the server construct your markup with data already in it, but still need to return some additional meta data about the results, such as the row or page counts, in JSON.

Now that you’re convinced there’s some performance gains here and some use cases to support it, what does the Javascript code look like?

Old code:


jQuery.post(
  "http://test.getify.com/mpAjax/search.php",
  'json={"id":3}',
  handleResponse
  "text/plain"
);

Becomes:


jQuery.post(
  "http://test.getify.com/mpAjax/search.php",
  'json={"id":3}',
  {
    "text/html":handleList,
    "application/json":handleData
  },
  "text/plain"
);

See how I very easily passed in an object literal {…} in place of the normal function reference for the “onsuccess” handler? mpAjax extends the core Ajax function to be able to parse a response, and if it sees the multi-part response format, it splits the parts and sends them to their appropriate handler, based on content-type in this example, or ordinal index if you so chose. So, each part is treated like a separate response, even though there was overhead for only one request/response, both client and server side.

And yes, built-in Ajax continues to function identically to before, even with mpAjax loaded on the page, if the responses don’t have multi-part formatting. So, there’s no reason you can’t add mpAjax to your existing application without changing anything else, and then begin optimizing new or existing Ajax calls by changing how the server responds.

And what about the server? How does it construct these responses? Well, the code logic is actually incredibly easy. Here’s some PHP for accomplishing that, though the logic is easily adaptable to any back-end language/platform.

function generate_part($data,$type="plain/text",$showLength=false) {
  $str = sprintf("!!!!!!=_NextPart_%d",+mt_rand());
  if ($type) $str .= sprintf("\nContent-Type: %s",$type);
  if ($showLength) $str .= sprintf("\nContent-Length: %d",strlen($data));
  return $str."\n\n".$data."\n";
}
echo generate_part($results_html,"text/html");
echo generate_part(json_encode($data),"application/json");

I hope the benefits of this approach are now apparent. My testing/benchmarking is showing some important gains.

And why all this talk of mpAjax on the flensed blog? Because with mpAjax, flXHR, and jquery.flXHRproxy, you can squeeze even more performance out of your cross-domain Ajax calls than ever before.

Here is a live demo of mpAjax, and also further documentation on the project. Enjoy!

Bookmark and Share

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

You must be logged in to post a comment.