The awesomeness of pjax
July 17, 2015

The awesomeness of pjax

Or how sometimes simpler is better.

pjax is a jQuery library created by Chris Wanstrath, the current CEO of GitHub. It uses AJAX (loading data with javascript without refreshing the page) and pushState (changing the URL of the page without refreshing the page) to create a faster browsing experience. It is faster because instead of loading the entire page on every click, a portion of the page is loaded and then swapped out in place of the old content. This means less elements to load and therefore faster browsing.

As we recently decided to use it, I thought it might be valuable to share how that came about and the benefits of our decision.

In order to demonstrate how the Lateral API recommends content we created a visualiser interface. It shows five random documents from the corpus that is being demoed and when a user clicks on one of them they are taken to a page showing related content recommendations for that document. If the user continues and clicks on a recommendation they are taken to a page showing related content for that recommendation, and so on.

We built the first version with Javascript to load the results with AJAX so that it would be fast and we could display some fancy transitions. This worked well but there was no URL state - if you found a good result, there was no way of linking to or sharing that page. Adding the functionality to allow for this was a bit daunting because we'd need to turn the visualiser into something like a single page application.

I started by convert the existing Javascript to a Backbone application. I chose Backbone because I'm quite familiar with it. I set aside an afternoon to work on it, but quickly stalled as I realised that it would take too long. We were discussing potential solutions to this problem, when Ben suggested that we scrap all the AJAX loading and make the visualiser behave like a regular website, where HTML is generated on the server and clicking a link takes you to that page, etc. Imagine that!

The only thing keeping me from doing this were the transitions, but we quickly decided that they could go in favour of the ability to link to results' recommendations pages. So I deleted all the unnecessary Javascript, converted the visualiser to use hyperlinks and generated the HTML on the server. This felt liberating. It was a much cleaner solution and far easier to maintain as all the views and rendering is on the server-side. It's also indexable by search engines and more accessible.

We had a few minor issues that I wasn't happy about. It was slower than before and there was an annoying white flash in-between page loads. Obviously these weren't deal breakers but I wanted to improve them. This is where I decided to try out pjax.

The implementation is very straight forward. To put it briefly, you create a <div> which contains the content you want to change:

&lt;div id="pjax-container"&gt;
&lt;!-- first five results --&gt;

Then you tell the jQuery plugin that when the user clicks on links with the data-pjax attribute, it should load that URL within the container using pjax:

$(document).pjax('a[data-pjax]', '#pjax-container', { timeout: 5000 });

Finally you add the data-pjax attribute to any links that need to be loaded with pjax. When one of these links is clicked, instead of loading the page as usual, a request is sent to the URL with a X-PJAX header. On the server-side when this header is detected, the layout isn't rendered and only the content is returned. This response is then rendered in the #pjax-container element.

If you're ever in a position where you're considering creating a single-page javascript app, my advice would be to ask yourself whether you really need to. A lot of the complexity of a single-page app can be removed by using pjax. It gives you the benefits of speed, accessibility, backwards compatibility and user experience with much less effort.

To see it in action check out some of our visualisers:

More in

By clicking “Agree”, you agree to the storing of cookies on your device to enhance site navigation, analyse site usage, and assist in our marketing efforts. View our Privacy Policy for more information.