[Posted by George V. Reilly]
Our Combiner Control has been a big win: it coalesces a large number of small files together, reducing the latency of loading the page.
A few months ago, our Home Page would make eight Ajax calls as it loaded, to fetch data to populate different parts of the page, such as the family calendar and shopping list panes. That behavior fell out of the modular design, but the two-connection limit forced these calls to be serialized, magnifying the latency of the page. Panes were initially rendered blank, with an all-too noticeable pause before the data appeared.
My first change was to aggregate the eight calls into one ‘mondo’ call. That helped.
// pseudo code
// other panes
GetAjaxData( "/Ajax/GetMondoData.ashx", RenderMondoData );
// Callback function, executed several hundred milliseconds later
CalendarPane.Fill( ajaxData.calendarData );
ShoppingPane.Fill( ajaxData.shoppingData );
// other panes
Later, I had the insight that I should send all that Ajax data down in the initial payload of the page. Now, the page can be rendered immediately: we've eliminated the latency of a roundtrip. Not only does this reduce the overall load time for the page, it significantly improves the perceived performance of the page, as panes are rendered sooner and with full data.
It's simple to make this work in ASP.NET:
static string HomePageDataJson()
DateTime startDate = DateTime.Now;
DateTime endDate = startDate.AddDays(9);
new HomePageData( startDate, endDate ) );
var homepagedata = <%= HomePageDataJson() %>;
var homepage = new HomePage( );
RenderMondoData( homepagedata );
The HomePageDataJson() function in the server script block creates the same object that the Ajax endpoint would have, then serializes it into a JSON string, using AjaxPro. This function could also be declared in a CodeBehind .cs page.
This JSON preloading technique could easily be adapted to other Ajax libraries and other Web servers.