Programming (back-end), Programming (front-end)

Getting started with PJAX with ASP.NET MVC

What is PJAX?

Pjax is a library that loads HTML from server side and puts it into a given placeholder (it could be a simple ‘div’). Underlying communication is done with AJAX so it is very fast and enhances a lot the browsing experience. But what is special in pjax?

pjax = pushState + AJAX

The best thing in it is that it utilises HTML5 History API (pushState API). It means that while loading only a part of a page we can completely change browser’s URL and use browser’s history to navigate through the pages. Awesome! To see live demos check out: https://github.com/defunkt/jquery-pjax or http://pjax.heroku.com/ (or wait for a movie in the end of the blog post).

HTML5 History API

HTML5 History API or pushState API is something new in Web development world. Oldschool history API was meant only as a way of going forward and backward in browser’s history, so the thing it could be used was to implement “” buttons:). Now the thing is completely different. HTML5 brings “pushState” method that stores a magic triple into history engine: the URL of the state, the title of the state and some additional data.

history.pushState({name: 'state1'}, "New URL", "newpage.html");

Any execution of the method forces the browses to change the URL and the title of the page but nothing more – it even does not chech whether a page with the given URL exists. The user can manually change the content of the page after running the method.
With pjax it all is wrapped in the form of jQuery plugin and the usage is extremely straightforward.

Real usage

HTML5 History API is commonly used when two pages with different URLs differs with only a small piece of information, sharing all the heavy layout, javascript files etc. Loading of the resources and rendering the page is expensive so the solution is to change the way some hyperlink works – they should modify history and URL (with pushState) and load (by AJAX) only the missing part of the page. Loading the page could be supported by showing a custom progress bar or firing other fireworks like animations etc.
The most popular usage (in our development environment) is GitHub directory tree which is extremelly fast and has a nice effect during the navigation. Facebook uses the API to load pages leaving the chat windows open for that time. GMail… is not using it, but I’ll left it for the finish.

ASP.NET MVC implementation

To implement our efficient application we need to provide two kinds of layouts: one complete layout and another only for PJAX requests. Anytime the page is loaded normally by the URL we should load the full layout but if there was PJAX request we should take the lighter one. Here is the code that should be a wrapper for our layout (i.e.: _ViewStart.cshtml):

@{
     if (Request.Headers["X-PJAX"] != null) {
          Layout = "~/Views/Shared/_PjaxLayout.cshtml";
     } else {
          Layout = "~/Views/Shared/_Layout.cshtml";
     }
}

Because PJAX puts a special header ‘X-PJAX’ into its calls we can distinguish them as  done in line 2.

The _PjaxLayout.cshtml could be implemented as following:

<title>@ViewBag.Title</title>@RenderBody()

The only responsibility here is rendering the page’s title and body (without any layout because it would be injected into the given placeholder).
The client side is even more simple. The only thing you need to do (despite adding script references) is registering pjax:

$('a').pjax('#main_content');

In the script above we said that for each hyperlink (‘a’ element) we should override its normal functionality and instead use PJAX to load the target document (‘href’) to a placeholder with id ‘main_content’. I’d say it couldn’t be simpler.
Here are some packages with ASP.NET MVC default applications utilizing PJAX. In the second one I use some effects (like animation and splitter) to enrich user experience:

PjaxMvcDemo.zip
PjaxMvcDemo_fireworks.zip

And the video showing PJAX in practice…

 

Pjax alternative

Some of you may think that it’s not mandatory to use PJAX or even pushState to achieve the same effect. And I’d say “Yes and No” at once. Here is the role of GMail mentioned before – it does not use pushState but is efficient and leaves the chat window openned! It uses something called HASH-HACK. When we add ‘#’ sign to the URL the browser thinks that we navigate to a region in the same page and it does not load any other page. That’s why the URL address changes but the chat window stays openned. The partial page load is done in a way similar to the PJAX version.
The biggest disadvantage of that hack is that URL must contain ‘#’ sign and because of that cannot be rated by any Search Engine. For e-mail client it is sufficient, but that’s all.

Summary

PJAX is an excellent jQuery plugin that simplifies usage of HTML5 History API. It is used to improve performance of the application and experience of a user dealing with it.
Have a nice time playing with it.

PS: Here is a reference to a blog post of the inventor of the way we connect PJAX to ASP.NET MVC 3: http://biasecurities.com/blog/2011/using-pjax-with-asp-net-mvc3/

Advertisements