PJAX Related performance improvements

To know about PJAX [(Click Here)(Pjax Railscast)][1]

Post from Kavita: [How to PJAX][2]

Pjax is a great solution when we want to do partial refreshing of page at the same time maintaining the history of user navigation, But it has few issues when the app grows

Basically PJAX works like this,

  1. Issuing a PJAX request to refresh the section of the page( eg: #conainer). Basically it fires an html ajax.
  2. Rails server handles the html request and renders the complete html page.
  3. These html template is parsed by the middleware, which removes the content that needs to passed for the client.
  4. Finally Client page does a html replace on the content for which we issued a pjax request.

So in the below example it will render complete body and from that it will pick the #container div and will send it to client for refresh.

  body
    #main_content
      ...  (May have some sql queries or logics for normal html page)
      ... 
      # container
        ...  (May have some sql queries or logics for normal html page)
        ...
        # container1
          ... (May have some sql queries or logics for normal html page)
          ...
        # container2
          ...  (May have some sql queries or logics for normal html page)

Now if we want to do pjax on #container2, then in that case, rails will still render the complete page including all sql queries that are above the #container2 as its html request, although they are not needed for pjax refresh. Now in this case we need to make sure that we are rendering just the #container2

In our RV App, this kind of rendering was taking more time on the server side and was hampering the performance on pjax requests.

How to avoid this? Simple Example would be to use if else

  1. In Application.html.haml, I used this as in our app where we were just refreshing the main container on partial
  - if params["_pjax"]
    = render 'layouts/container'
  - else
    !!!
    %html{lang: "en"}
      %head
        %meta{charset: "utf-8"}
        ...  ( It had few queries with for fetching some user level data)
        ...
  1. In some extreme scenarios we can use content for so that we can control the content rendered inside pjax.

For more details on [content_for (Click here)(content_for)][3]

In my case this refactor improved the performance by good margin, i.e around 300 - 500 ms.

Thats it!!!
[1]: http://railscasts.com/episodes/294-playing-with-pjax?view=asciicast
[2]: http://knowbuddy.kiprosh-app.com/kyu_entries/pjax-in-rails
[3]: http://apidock.com/rails/ActionView/Helpers/CaptureHelper/content_for