The Subtleties of Rails 4 - Turbolinks
Contents of the Rails 4 Subtlety Cycle
- Cache digests
- Thread safety
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.
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 .
//= 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?
Problems with Existing Scripts
Actually, here is the code that is having problems:
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:
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:
$('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.
Thanks for attention!
About all errors found, translation inaccuracies and other similar things, please inform in PM.
- The source code of the application from the lesson
- Gem Turbolinks
- Bug Tracker Turbolinks
- Turbolinks Speed Test
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