📜 ⬆️ ⬇️

Rails 4 Subtleties - Turbolinks



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



The content of the cycle "The Subtleties of Rails 4"



Turbolinks allows you to speed up almost any Rails application, since it loads only the body of the page. Yes, this is all done with javascript. In this article we will test the work of the heme on the application written on third rails.

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


Adding Turbolinks

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

/ Gemfile
gem 'turbolinks' 

Now it is necessary to add a line for adding turbolinks to the application manifest in Javascript:

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

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

After overloading the server with the rail and climbing a bit on the application, you may not see much difference. To check if Turbolinks itself works, you need to open browser's network inspector and then browse the site. In my case, after the steps described above, I saw that when I went to any page it was loaded in its entirety, thus the conclusion: heme did not work. This can happen if your browser is not supported by Turbolink, in which case you should change it (and, preferably, to something known), or upgrade (if possible). Gem expects to use the most recent version of one of the popular browsers. Otherwise, it simply will not 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 developed website in it. By launching the web inspector and clicking on the links it will be seen that the page is not completely reloaded, since the gem is now working and turbolinks.js is already generating an ajax request for the page to be opened.



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

Turbolinks for all links on the page listens for a click event. As soon as it occurs, a GET request is made to the necessary page through JavaScript and after that the obtained data is analyzed, and then the title and body elements are updated. Heme 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 seems to work quite well with Turbolinks, but nevertheless, even in it there are problems with existing JavaScript scripts. To see this problem is very simple, you just have to try to switch the value in the checkbox of the task. Nothing will happen. At all. However, if you manually refresh the page, the problem magically disappears.

Actually, here is the code with which problems arise:

/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. Once it has occurred, the checkbox form is sent to the server, after which the task is marked as completed.

Get accustomed to the first line of code. It is very important, because it is in it that it waits for the ready event for the page, which is triggered only after the DOM of the page has completely loaded. Therefore, if you do not use this code, then jQuery will try to attach event'y to checkboxes before they are loaded.

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

/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 we 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 is restored: when ticking the checkbox of the task, it will be automatically marked as completed. And also an easily completed task can be turned into an incomplete one.

To solve similar problems, you can use the Jquery Turbolinks gem . In addition, there is another solution to bypass these pitfalls. Instead of finding items and tracking their click events, you can listen to a click event for 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 check that the DOM is loaded. And there is also an additional advantage: the code will correctly process all tasks with checkboxes added using AJAX.

It would be a good idea to follow the Turbolinks bug tracker , because at the time of publishing the article he had serious problems with third-party libraries, such as Twitter Bootstrap, Jquery UI Calendar. At the same time, we are working on them to add compatibility.

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

Looking at a bunch of problems you might think: "Is it worth it?". Turbolinks speed test can help in solving, from which it can be seen that in some cases the page load increases 2 times. Of course, all the applications are different, but you can try the gems at your place and check how the site's responsiveness improves.

If you want to use Rails 4 and at the same time Turbolinks you absolutely dislike or do not fit, then you can safely turn it off. 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!

All errors, inaccuracies of translation and other such things, please report in a personal.



application



Subscribe to my blog !

Source: https://habr.com/ru/post/167161/


All Articles