Lazy Websites

  • Martin Fowler
  • September 22, 2011

We often build websites that showcase a large amount of high quality media in the form of images, text, and video. While this media makes for a compelling user experience it often comes at the cost of bandwidth in terms of network throughput and server processing power. It is our challenge as developers to show as much of this high quality media in as little time as possible, and make sure it does not negatively impact the user’s browsing experience. I’d like to share a technique known as Lazy Loading which we have used to show a large number of high quality images with little effect on the visitor’s browsing experience.

Lazy Loading is a design pattern that is used to defer the loading of information or content until it is needed. This pattern has several implementations that can be used to improve the performance of websites and applications. The method we will focus on is called Lazy Initialization, in this pattern content will not be loaded until you actually need it. If you have any sort of click navigation, or rotating features, or AJAX style design features, then it could become very easy for you to render content only when content is needed. Let’s look at the workflow of a lazy loading solution and what it actually does to provide us with this benefit.

We will implement our lazy loading using JQuery AJAX and .NET Webservices. On the client side, we use JQuery to create content control objects that will make an AJAX style call to an ASP.NET Webservice. This will perform the calculations and content fetching and return the required data in a JSON format. The data is then processed through JTemplate to produce the output.

lazy loading uml for websites

Client calls out to a .NET Webservice and request a list of items from Sitecore. Then it will process the results from this request and compile that information into a JSON return object. The following code shows an example of a JavaScript/JQuery object that includes an AJAX method for data retrieval:

this.sendRequest = function (url, postData) {
			var data = { "scriptPostData": postData };
			$.ajax({
				type: 'POST',
				url: url,
				contentType: "application/json; charset=utf-8",
				dataType: 'json',
				data: JSON.stringify(data),
				success: this.cfg.OnDataSuccess
			});
		};

The config value for OnDataSuccess is a callback method inside the Javascript object that is used to display the return results. For example, you can use a method that takes the data in the return object and displays the information using a template plugin like JTemplate. For example:

this.DefaultProcessData = function (response) {
			var items = { items: response.d.ContentItems };
			var cfg = JSON.parse(this.data);
			var contentArea = jQuery(cfg.scriptPostData.PlaceholderSelector);
			var oldHtml = contentArea.html();
			contentArea.setTemplateURL(cfg.scriptPostData.TemplateUrl, null, { filter_data: false });
			contentArea.processTemplate(items);
			contentArea.prepend(oldHtml);
}

This type of implementation is used in a “Load More” scenario where the list renders the first (say 5) content objects. When the client clicks a button, it fires off a request to the content control object that uses a webservice to pull the next set of information. Next we will take a look at the ASP.NET Webservice’s side of Lazy Loading.

If you are not familiar with the process of creating a Webservice in Visual Studio, then take a look at this MSDN article. After creating the webservice it should look something like this:

webmethodbasic code for lazy loading on websites

There is one additional thing requirement that is needed in the Webservice to allow JQuery to make the call. You will need to uncomment the class decoration for [ScriptService]

Now its time to implement your own Webmethod to process the request from the AJAX call. To make things easier, you should first implement 2 data contracts. The first data contract will represent the values being sent to the Webservice from the AJAX JSON POST request, while the second data contract will represent the return value. This return value will be converted to a JSON string that can then be parsed and used in the return method. Here is how we create the classes inline with the Webservice code:

postdata method code for lazy loading in websites

returncontent method code for lazy loading in websites

contentitem method code for lazy loading in websites

Now that we have the data contracts, we can access the information that the JQuery AJAX call is sending to us, and the JQuery return method will be able to understand our responses. Our new WebMethod looks like this:

new webmethod basic code for lazy loading in websites

The GetContent method retrieves the Content Item objects and then inserts them into the Return Content object. The return object is then serialized into a JSON string (which is handled by ASP.NET behind the scenes so there's no need to worry about this part) and then sent back to the AJAX request call. Finally, when the AJAX call receives the data it fires off the OnDataSuccess callback method to handle and process the return results.

That's all there is to creating and using the Lazy Initialization pattern using JQuery and ASP.NET Webservices. In our testing we have seen pages that would have taken up to 20 to 30 seconds to load, but by using Lazy Loading they have been reduced to roughly 500 milliseconds. I would consider this to be a mission accomplished and would say that here is proof that it pays to be Lazy!

Here are a couple of notes to consider before implementing this yourself.

  1. The Request type for the JQuery AJAX call *must* be POST. Because of this, you can forget about using services to cache the response from the request. Instead, use localized caching methods to speed up requests. For instance, we make our cache key named based on values of input to the GetContent webmethod. Applying this method will greatly reduce the load on your servers when users send the request to load more content. This is what our cache key looks like:
    cache key for lazy loading in websites

    We then use a cache object to insert / retrieve values of the cache based on this key.

  2. You can implement the “GetContent” method with any signature you like, but he data you pass to it from the JQuery must match the signature. So in this case you see that the JQuery sends in the post data a JSON stringafied object that within it contains a variable “scriptPostData” which matches up to the name of the variable in the signature of the WebMethod. While you don’t need to use a single object for the information you pass to the Webservice, it is much easier to use this PostData object, than it is to list out 10+ variables in the WebMethod signature.

To read more about the other types of Lazy Loading (Virtual Proxy, Virtual Holder, and Ghost), please see the Lazy Loading article on Wikipedia.