“We believe the PJAX are the future.” — Whitney Houston
The PJAX library essentially encapsulates the Ajax + pushState + HTML update flow. The native clicks and submits of PJAX-enabled links and forms are hijacked and emulated with Ajax. The end result of such navigation is supposed to be identical to the page refreshing natively.
When to use
PJAX should be used:
- To speed up page navigation that our users perform often;
- To speed up dynamic result of some forms, such as search or filtering.
Avoid using PJAX for:
- As a general tool for any sort of dynamic content update on the page, especially if the URL doesn't need to be updated;
- Site functionality that is not often exercised, e.g. an admin feature that gets used only a few times in a month;
- Transition between pages that don't share a similar layout.
A link is considered to be PJAX-enabled if it's “tagged” with
attribute and is nested under a container tagged with
attribute, or references a container by ID:
<div id="js-pjax-container" data-pjax-container> <nav data-pjax> <ol> <!-- all of the navigation links will use PJAX --> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> <li><a href="/faq">FAQ</a></li> </ol> </nav> <!-- this link will use PJAX --> <a href="/modern" data-pjax>This will load fast</a> <!-- ordinary link will not use PJAX --> <a href="/classic">Native page load like it's 1995</a> </div> <!-- not nested, but references the PJAX container explicitly --> <a href="/" data-pjax="#js-pjax-container">The container is over there</a>
A form is considered to be PJAX-enabled if it's tagged with
<div id="js-pjax-container" data-pjax-container> <form action="/create" data-pjax> <!-- form stuff --> </form> </div>
Handling and cancelling the
pjax:click event allows us to prevent PJAX
behavior on a case-by-case basis. For instance, PJAX is only allowed within the
#js-repo-pjax-container element if the link to be followed leads to a resource
under the same GitHub repository. Links to any other repository, such as forks,
will be followed using native browser behavior.
The Rails application is configured to render all PJAX requests using the
pjax.html.erb layout by default instead of the more bulky application
pjax? helper is available to distinguish between PJAX requests
when it's absolutely necessary.
Whenever any of the assets change on the server, the PJAX responses carry metadata that will force a full refresh on clients that still have the old assets. This is to prevent browsers continuing to load new pages while having stale versions of CSS/JS assets in effect.
If a template needs to set any meta tags specific to the page, it should do so
content_for :head block and tag the meta items with
data-pjax-transient attribute to indicate that they are to be injected in
<head> on PJAX load, but removed when we navigate away:
<% content_for :head do %> <link rel="alternate" href="<%= request.path %>.patch" type="text/plain+patch" data-pjax-transient> <meta name="diff-view" content="<%= diff_view %>" data-pjax-transient> <% end %>