Code: AJAH pattern

Chapter 8 - Ajax Optimization

Asynchronous JavaScript and HTML (Ajah) is a pattern whereby you pass back fully rendered HTML responses rather than XML or JSON formats.

For example, with our "Hello World" example, our response with an XML packet would be like this:

<?xml version='1.0' encoding='UTF-8'?><message id='message1'>Hello World to user from
63.210.161.190 at 10:54:00 AM</message>

In an Ajah style, it might look like this:

<h3>Hello World to user from 63.210.161.190 at 10:54:00 AM</h3>

Or it might just look like an unmarked-up string, such as this:

Hello World to user from 63.210.161.190 at 10:54:00 AM

Consumption of an Ajah-style response is simply a matter of setting the innerHTML value of some target element. For example, instead of a callback function handling an XML response packet, like this:

function responseCallback(xhr)
{
    if (xhr.readyState == 4 && xhr.status == 200)
    {
        var parsedResponse = xhr.responseXML;
        var responseString = parsedResponse.getElementsByTagName("message")[0].firstChild.nodeValue;
        var output = document.getElementById("output");
        output.innerHTML = responseString;
    }
}

you would simply have one that directly consumes the content, such as this:

function responseCallback(xhr)
{
    if (xhr.readyState == 4 && xhr.status == 200)
    {
        var output = document.getElementById("output");
        output.innerHTML = xhr.responseText;
    }
}

If you then used chaining, you could further compress the result, like so:

function responseCallback(xhr)
{
    if (xhr.readyState == 4 && xhr.status == 200)
    document.getElementById("output").innerHTML = xhr.responseText;
}

before applying variable name reductions or other minimization techniques. This particular callback is so small now that it is probably more appropriate to inline it, as shown here:

if (xhr)
{
    xhr.open("GET","sayhello.php",true);
    xhr.onreadystatechange = function( ){if (xhr.readyState == 4 && xhr.status ==
    200)document.getElementById("output").innerHTML = xhr.responseText;};
    xhr.send( );
}

With the reduced code needed from the Ajaxpattern and having applied all the techniques discussed previously, our final compressed solution looks like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/
xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><title>Ajax
Hello World</title><script type="text/javascript">d=document;M="Msxml2.
XMLHTTP";function c( ){try{return new XMLHttpRequest(
)}catch(e){}try{A=ActiveXObject;return new A(M+".6.0")}catch(e){}try {return new
A(M+".3.0")}catch(e){}try {return new A(M)}catch(e){}try {return new A("Microsoft.
XMLHTTP")}catch(e){}}function s( ){var x=c( );if(x){x.open("GET","sayhello.php");x.
onreadystatechange=function( ){if(x.readyState==4&&x.status==200)d.
getElementById("o").innerHTML=x.responseText;};x.send( );}}window.onload=function(
){d.getElementById("b").onclick=s}</script></head><body><form action="#"><input
type="button" value="Say it!" id="b" /></form><br /><br /><div id="o"> </div></
body></html>

The very terse code of this page weighs in at a svelte 947 bytes, for a total savings of nearly 37%; with further gzipping you can save even more (as high as 62%). However, continuing our efforts is somewhat foolish because we’re already below the minimum packet size we’d typically encounter in TCP. Thus, it really buys us little to continue.