We all hate waiting for websites to load before we can start using or surfing it. Internet has a come a long way with great speeds to decrease this time, but this has just made the user more impatient. After a lot of research through the decade, it has been found out that on an average a user would not wait for more than 4 seconds for a web page to load. With such short time requirements, even decrease of milliseconds in the loading time can effect the web-site’s business greatly. While on client-side, improving Internet connection is obviously a way to load websites faster, even web developers can develop websites with numerous techniques that will help their site to load faster. We are here to talk about one such technique, Pjax.
Pjax is made up of two terms, pushState and ajax. Before diving into pjax, let’s have a brief look at what ajax and pushState are.
XMLHttpRequest object to communicate with servers. It can send and receive information in various formats, including JSON, XML, HTML, and text files. AJAX’s most appealing characteristic is its “asynchronous” nature, which means it can communicate with the server, exchange data, and update the page without having to refresh the page.
Here’s an example. Let’s say a person navigates from the homepage of a site to the Help page. We’re loading the content of that Help page with Ajax. That user then heads off to the Products page which we again load and swap out content with Ajax. Then they want to share the URL. With the History API, we could have been changing the URL of the page right along with the user as they navigate, so the URL they see (and thus share or save) is relevant and correct.
The pushState method of the History API changes the current URL of the browser to a specified URL and also manipulates the browser history, so that the browser back button does not create a problem.
For example, let’s suppose we are at https://www.foobar.com. Now, we click a button that redirects us to https://www.foobar.com/foo.html. After this, we againn click a button that fires the pushState method that changes the URL to https://www.foobar.com/bar.html but does not change the page, as in nothing except the URL of the browser changes. Now, if we click on back button, it will take us to https://www.foobar.com/foo.html. That means, pushState does not only change the URL of the page but behind the scenes it also manipulates the history so as to add an element to the stack with the changed URL. Thus, back button will take us to the previous URL instead of the previous web page.
Pjax is just the combination of these two concepts. Pjax works by fetching HTML from your server via AJAX and replacing the content of a container element on your page with the loaded HTML. It then updates the current URL in the browser using pushState. This results in faster page navigation for two reasons:
- No page resources (JS, CSS) get re-executed or re-applied.
- If the server is configured for Pjax, it can render only partial page contents and thus avoid the potentially costly full layout render.
A Basic Example
To install Pjax through npm –
$ npm install pjax
To install it through bower –
$ bower install pjax
You will have to include the pjax.js file in your html files to access the Pjax functionality.
I installed it through npm and will be using the same for starting the server as well. It doesn’t matter what you use to start the server or what MVC framework you use, it will work on everyone of them just fine.
After running above commands, we can straight away dive into the code. To demonstrate the working of Pjax, we will be making two links, one that will be using Pjax to change the content of a div and change the URL, and another one that will not be using Pjax and thus will be loading the whole page. Both links will re-direct to the same page so that we can see the difference clearly.
Ok, so my code for main page looks something like this (main.html) –
And code for the common page looks something like this (common.html) –
In this code, we have initialized the Pjax class and passed on some values.
elements are comma-separated values of those elements on which Pjax would take effect. Here,
a.js-Pjax are the anchor elements with class as js-Pjax.
selectors are the containers that will get their content replaced by Pjax. Note that both the HTML pages using Pjax have to have the same layout and same number of DOM elements at the same position. If there’s any change in any of these things, Pjax will go into fall-back mode (it will just do nothing) and will load the page as it normally would. So, in selectors we put ids or classes of those elements, whose contents we want to be replaced by the other page’s same DOM element, that will be called on the click of an element defined in elements.
We are all done with our Pjax enabled site! Now we will start our server. NPM users can start it by using the command
npm run <script-name> .
Now when you open up the site, you can see the home page that we built in main.html. Now when you click on ‘First Link’, you can see that the URL and the content of the div under the links have changed. It looks like you navigated through the site but nothing essentially changed except the things we defined while building Pjax. Now if you go back and click on ‘Second Link’ you can see an alert box with text ‘An alert box’ appearing on your window. While we have used the same JS on both the pages, ‘First Link’ didn’t show the alert box while the ‘Second Link’ did. This is because Pjax only changes the URL and the content of the containers defined while building it, it does not even re-execute JS or re-apply any CSS. This saves a lot of time when loading heavy sites.
Below video shows the behavior of the site we just built –
Github repository for the above code – https://github.com/akshanshjain95/pjax-tutorial
Github repository of Pjax – https://github.com/MoOx/pjax
Thanks for reading. I hope it helped you!