The Subtleties of Rails 4 - Turbolinks

Original author: Ryan Bates
  • Transfer
  • Tutorial


A gem called Turbolinks is capable of speeding up your application pretty well using JavaScript to update the content on the page. It is enabled by default in Rails 4, but I will show how you can use it now in programs written in Rails 3. You will also learn about some of the pitfalls.



Contents of the Rails 4 Subtlety Cycle



Turbolinks allows you to speed up almost any Rails application, since it only loads the body of the page. Yes, all this goodness is done using JavaScript. In this article, we will test the operation of the gem on an application written on third rails.

The site itself is quite simple - it is a set of projects with its list of tasks that must be completed. Each new task is marked as unfinished, but with a slight movement of the mouse (or rather, clicking in the corresponding checkbox), the task becomes complete.



Adding Turbolinks

Now add Turbolinks to our application and see how it all works. First of all, enter the gem name in the gemfile and then run bundle install .

/ Gemfile
gem 'turbolinks'

Now you need to add a line in the application manifest to Javascript to add turbolinks:

/app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .

By the way, the gem does not require jQuery, which in some cases can be very convenient.

Having rebooted the rail server after that and climbing a little according to the application, maybe you will not see much difference. To check if Turbolinks actually works, you need to open the network inspector of the browser and then wander around the site. In my case, after the steps described above, I saw that when I go to a page, it loads completely, so the conclusion is: the gem didn't work. This can happen if your browser is not supported by Turbolink, in which case it is worth changing it (and, preferably, to something known), or updating (if possible). Gem expects the latest version of one of the popular browsers to be used. Otherwise, it simply won’t work, but the application will function normally without it.


In my case, I changed my browser to a new version of Chrome and opened a website under development in it. By launching the web inspector and clicking on the links, it will be seen that the page is not loading completely, since the gem is now working and turbolinks.js is already generating an ajax request for the page to open.



Using a gem allows the site to load faster because the browser does not re-interpret the JS and CSS code, but how does it work?

Turbolinks for all links on the page listens for the click event . As soon as it happens, a GET request is made to the desired page via JavaScript and after that the received data is analyzed, and then the title and body elements are updated. The gem also uses the Push State API to change the URL of the updated page. This technique is very similar to PJAX.



Problems with Existing Scripts

The application written for this tutorial would seem to work quite well with Turbolinks, but nevertheless, it even has problems with existing JavaScript scripts. To see this problem is very simple, you just try to switch the value in the task checkbox. Nothing will happen. At all. However, if you manually refresh the page, then the problem will magically evaporate.

Actually, here is the code that is having problems:

/app/assets/javascripts/projects.js.coffee
jQuery ->
  $('.edit_task input[type=checkbox]').click ->
    $(this).parent('form').submit()

The code expects a click event in one of the task checkboxes. As soon as it happened, the form with the checkbox is sent to the server, after which the task is marked as completed.

Take a look at the first line of code. It is very important, because it is there that it waits for the ready event for the page to fire only after the entire DOM of the page has loaded. Therefore, if you do not use this code, then jQuery will try to attach events to the checkboxes before loading them.

When using Turbolinks, this callback is executed only once, when the page loads. This brings us to another important point: when we go to another page, thanks to the features of the gem described above, we technically remain on the same page. However, Turbolinks itself generates several different events when a new page loads, and one of them is page: load . This allows you to emulate loading the DOM:

/app/assets/javascripts/projects.js.coffee
ready = ->
  $('.edit_task input[type=checkbox]').click ->
    $(this).parent('form').submit()
$(document).ready(ready)
$(document).on('page:load', ready)

Now you can define the ready variable , save our long-suffering function in it, and then pass the variable to document.ready and page: load . Thus, events are now attached to checkboxes, regardless of whether Turbolinks is used or not. Now the functionality has been restored: when ticking the checkbox of the task, it will be automatically marked as completed. And also easily completed task can be turned into incomplete.

To solve similar problems, you can use the Jquery Turbolinks gem . In addition, there is another solution to circumvent such pitfalls. Instead of finding elements and tracking their click events, you can listen to the click eventfor the entire document and if it occurs, check that it was called for the checkbox with the task:

/app/assets/javascripts/projects.js.coffee
$('document').on 'click', '.edit_task input[type=checkbox]', ->
    $(this).parent('form').submit()

With this approach, it is not even necessary to verify that the DOM is loaded. And there is also an additional advantage: the code will correctly handle all tasks with checkboxes added using AJAX.

It’s a good idea to keep an eye on the Turbolinks bug tracker , since at the time of publication of the article it had serious problems with third-party libraries such as Twitter Bootstrap, Jquery UI Calendar. At the same time, work is underway on them in order to add compatibility.

Nevertheless, there are infrequent situations in which, when returning to the previous page, Turbolinks nicely makes a POST request instead of a GET. How to solve this problem? Just disable Turbolinks in such situations. These childhood diseases should be cured in the near future.

Looking at such a bunch of problems, you might think: “Is it worth it?” The Turbolinks speed test can help in solving this , from which it can be seen that in some cases the page load is doubled. Of course, all applications vary, but you can try the gem on your own and see how the responsiveness of the site improves.

If you want to use Rails 4 and at the same time you absolutely do not like or do not fit Turbolinks, then you can safely disable it. To do this, remove the gem from the gemfile, and then remove the corresponding line with require from the main JavaScript manifest of the application.

Thanks for attention!

About all errors found, translation inaccuracies and other similar things, please inform in PM.



application



Subscribe to my blog !

Only registered users can participate in the survey. Please come in.

Will you use Turbolinks in your projects?

  • 14.7% Already actively using! 69
  • 23.7% I will definitely try and make an effort for a successful implementation. This is the future. 111
  • 28.6% I will try, but I have a healthy skepticism towards such ideas. 134
  • 16.2% No, and I don’t need such happiness. 76
  • 16.6% Yes, we would at least grow to the third rails, and you are asking such terrible questions! 78

Also popular now: