Speeding up your app’s navigation with Turbolinks
Tags: beginners, rails, optimization, javascript
Published: 2018-05-23 13:13:22

---
title: Speeding up your app’s navigation with Turbolinks
description: Turbolinks is an optimization that increases the perceived performance by being smart about switching pages and reloading assets in your app.
cover_image: https://blog.appsignal.com/images/blog/2018-05/turbo.jpg
canonical_url: https://blog.appsignal.com/2018/05/23/speeding-up-your-apps-navigation-with-turbolinks.html
tags: beginners, rails, optimization, javascript
published: true
---

Turbolinks is an optimization that increases the *perceived* performance by being smart about switching pages and reloading assets in your app. Unlike [conditional GET requests](https://blog.appsignal.com/2018/05/01/client-side-caching-in-rails-conditional-get-requests.html), it doesn't require any changes to the Ruby code in your Rails app itself. Turbolinks 5 is a JavaScript library that works everywhere (even without Rails, like on static pages) and degrades gracefully on unsupported browsers.

## Turbolinks 5

[Turbolinks](https://github.com/turbolinks/turbolinks) has been bundled with Rails and included in new applications by default since Rails 4. Rails 5 ships with Turbolinks 5, which is a rewrite of what's now called Turbolinks Classic.

Although it ships with Rails, the new version of Turbolinks is a pure JavaScript library that can be used on any HTML page putting it in a `<script>` tag on the page, or including it into the app's JavaScript bundle.

When included, Turbolinks will automatically find all links that point to the same domain, and attach a click event listener. Any clicks on those links will be intercepted. Instead of following the links like normal, it request the linked page in the background via JavaScript using [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest). Then, four things happen:

1. A copy of the current page is stored in Turbolinks' cache to be used later
2. It *replaces* the current page’s `<body>` with the `<body>` from the XHR result
3. It *merges* the current page’s `<head>` with the `<head>` from the XHR result
4. It changes the URL in the browser using the History API


By merging the `<head>` tags, the browser doesn’t have to reload and rerender assets like CSS and JavaScript files that are present on both pages. This can speed up your app significantly, especially if you have a lot of assets that are reused on most of your pages.

![](https://blog.appsignal.com/images/blog/2018-05/turbolinks-network.png?)

In a fresh Rails 5 app with some views, you can see Turbolinks in action by navigating around by clicking links and pressing the back button. In your browser's network tab, you'll see requests for pages loaded through Turbolinks marked as "xhr". Also, your assets won't be reloaded for every request.


## Caching and page previews

To speed up subsequent requests to the same page, Turbolinks maintains a cache of recently visited pages. This allows rendering the previous page immediately when pressing the back button, for example.

To speed up the perceived performance of slow pages, Turbolinks will show a preview of the page if it exists in the cache. After clicking the link, the cached version is shown while the fresh version loads.

## Caveats

Turbolinks reimplements some of your browser's default features, so some things work differently with Turbolinks enabled than without.

### `turbolinks:load` and `<script>` tags

Since the page isn't refreshed after every link click, loading JavaScript on page load using `window.onload` or `DOMContentLoaded` doesn't work anymore. To fix that, Turbolinks supplies the `turbolinks:load` event, which you can use instead:

``` javascript
document.addEventListener("turbolinks:load", function() {
  // ...
})
```

### Browser loading states

When switching between pages, the browser won’t show the loading indicator in your browser because the request is executed in the background.

In an attempt to fix that, Turbolinks will show a blue bar (which can be styled with CSS) at the top of the page after 500 milliseconds to indicate that the page is loading.

![](https://blog.appsignal.com/images/blog/2018-05/turbolinks-loading.png?)

# `$ rails new --skip-turbolinks`?

Turbolinks 5 has come a long way since Turbolinks Classic, when Turbolinks seemed to be that thing you skipped when generating a new Rails app. Being a gracefully degrading pure JavaScript plugin that doesn't depend on Rails now, it works out of the box for most apps, if you keep the caveats in mind.

In return, Turbolinks gives a nice speed boost and prevents your static assets from being reloaded on every page view, which saves some network requests. When generating a new Rails app, try keeping Turbolinks in to see what it does. On existing apps, give Turbolinks a try!

That concludes our overview of Turbolinks. Are you using Turbolinks in any of your apps? We'd love to hear from you! Also, we're curious to how you liked this and previous articles in AppSignal Academy, or what you'd like to read about next at [@AppSignal](https://twitter.com/appsignal).