Rails

【Rails】初心者向け!画面遷移の高速化を行うTurbolinksについて図を用いて詳しく解説

Rails

 

今回は、画面遷移の高速化を行うライブラリ「Turbolinks」について解説したいと思います。Turbolinksは非常に便利なライブラリですが、Railsではデフォルトで導入されており、概念や使い方を知らないとエラーを引き起こす原因にもなりかねません。ぜひ、この機会にTurbolinksについての理解を深めていきましょう。

JSの特定のメソッドが発火しなくなったり、ページが複数回呼ばれたりと不具合の原因にもなりかねない、癖のあるライブラリだね。

Turbolinksとは

Turbolinksとは、Rails4から正式導入された画面遷移を高速化させるライブラリです。Turbolinks自体はJavaScriptのライブラリとして提供されていますが、Railsでは利用しやすいようにGemとしてデフォルトで組み込まれています。

Rails4が導入されたのは2016年です。

Turbolinksの仕組み

Turbolinksはページ遷移を高速化させる仕組みであると前述しました。では、どのような仕組みで画面遷移を高速化させているのでしょうか?

Turbolinksを用いた画面遷移の仕組みを簡単に図示化したものが以下になります。

Turbolinksを用いた画面遷移の仕組み
  1. リンクのクリックイベントが発火
  2. 画面遷移を阻害し、非同期でリクエストを送る
  3. HTMLをレスポンスとして返す
  4. headタグに含まれているJSとCSSが、現在のページと一致しているかチェック
  5. headタグはマージ、bodyタグは差し替えることで画面遷移が起きたように見せかける

①リンクのクリックイベントが発火

Turbolinksは同じドメイン内のaタグを監視しており、クリックされることでTurbolinksの仕組みが動き出します。

②画面遷移を阻害し、非同期でリクエストを送る

Turbolinks intercepts all clicks on <a href> links to the same domain. When you click an eligible link, Turbolinks prevents the browser from following it. Instead, Turbolinks changes the browser’s URL using the History API, requests the new page using XMLHttpRequest,

参考:https://github.com/turbolinks/turbolinks

Turbolinksはリンクがクリックされたことによる画面遷移を阻害し、History APIを用いた非同期のリクエストを送ります。

History APIとは、ブラウザのページ遷移履歴を管理・操作するためのAPIです。

③HTMLをレスポンスとして返す

and then renders the HTML response.

参考:https://github.com/turbolinks/turbolinks

リクエストを受けたサーバーは、HTMLをレスポンスとして返します。

④headタグに含まれているJSとCSSが、現在のページと一致しているかチェック

レスポンスとして返ってきたHTML要素にある、heasタグ内のJSとCSSが現在のページと一致しているかどうかをチェックしています。これは次の動作である、置き換えを行うための準備にあたります。

⑤headタグはマージ、bodyタグは差し替えることで画面遷移が起きたように見せかける

During rendering, Turbolinks replaces the current <body> element outright and merges the contents of the <head> element.

参考:https://github.com/turbolinks/turbolinks

Turbolinksは現在の<body>要素を置き換え、<head>要素の内容はマージします。そうすることで、あたかも画面遷移が起きたように見せているのです。

トラブルシューティング

ここではTurbolinksが原因で引き起こされるエラーの解決方法について紹介したいと思います。Turbolinksが原因で起きるエラーは主に以下の3つです。

  • jQueryのreadyイベントが発火しない
  • Windowのloadイベントが発火しない
  • metaタグが更新されない

jQueryのreadyイベントが発火しない

Turbolinksでページ遷移した場合、jQueryのreadyイベントが発火しません。言い換えれば、$(function(){})に入ってる処理が実行されないということになります。

jQueryのreadyイベントとは、DOM(HTML)の読み込みが完了した際に実行されるイベントです。readyは省略が可能で、以下の2つのコードは同じ意味を表します。

$(document).ready(function(){
  // 処理内容
});

$(function(){
  // 処理内容 
});

 

readyイベントが発火しないエラーの解決方法は3つあります。

  1. 「turbolinks: load」を使用する
  2. 「jquery-turbolinks」というGemを使用する
  3. TurbolinksをOFFにする

①「turbolinks: load」を使用する

readyイベントが発火しない場合は「turbolinks:load」というオプションを使用することで、読み込みが正常に行われます。

$(function(){
  // 処理内容 
});

↓ 以下のように編集

$(document).on('turbolinks:load', function() {
  // 処理内容
});

 

②「jquery-turbolinks」というGemを使用する

readyイベントの読み込みを行なってくれる「jquery-turbolinks」というGemがRails側で用意されています。

しかしGemを導入すれば完了というわけではなく、documentに登録したイベントハンドラが複数回実行されてしまうといった別の不具合が起きる可能性があります。

詳しくはGithubのトラブルシューティングを参考にしてください。

Github:https://github.com/kossnocorp/jquery.turbolinks

 

③TurbolinksをOFFにする

上記2つの解決法でも良いとは思いますが、TurbolinksそもそもをOFFにすることも対処法の1つに入れていただけたらと思います。

TurbolinksをOFFにする手順は以下の通りです。

①Gemfileの以下の記述をコメントアウトする
gem ‘turbolinks’, ‘~> 5’

②bundle installを実行

③app/javascript/packs/application.jsの以下の記述をコメントアウトする
require(“turbolinks”).start()

④app/views/application.html.erbの「‘data-turbolinks-track’: ‘reload’」の部分を消す
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
個人的にはTurbolinksそもそもをOFFにするのが良いと思います。

Windowのloadイベントが発火しない

jQueryのreadyイベント同様、windowのloadイベントも発火しません。

こちらの解決方法は以下の2つになります。

  1. 「turbolinks:load」を使用する
  2. TurbolinksをOFFにする

「turbolinks:load」を使用する場合は、以下のように記述を変更してください。

window.addEventListener('load', (event) => {
  // 処理内容
});

↓ 以下のように変更

document.addEventListener('turbolinks:load', function() {
  // 処理内容
});
TurbolinksをOFFにする手順は前述した通りです。

metaタグが更新されない

Turbolinksの仕組みを見て分かる通り、更新が行われるのはheadタグに含まれるtitleとbodyタグのみです。

そのため、headタグ内にあるmetaタグは更新の対象外になります。

この問題はbodyタグの中にmetaタグを更新するスクリプトを記載することで解決できますが、Rails生みの親DHHが推奨していません。

metaタグを更新する方法:
https://github.com/turbolinks/turbolinks-classic/pull/165

推奨はしていないけど、代わりになる解決方法はあるんだろうか。

参考

Turbolinks Github:
https://github.com/turbolinks/turbolinks

Turbolinks-Rails Github:
https://github.com/turbolinks/turbolinks-rails

jQuery Turbolinks:
https://github.com/kossnocorp/jquery.turbolinks/blob/master/README.md

metaタグを更新する方法:
https://github.com/turbolinks/turbolinks-classic/pull/165

Turbolinks チートシート:
https://qiita.com/morrr/items/54f4be21032a45fd4fe9

 

 

今回は画面遷移の高速化を行うライブラリ「Turbolinks」について解説しました。Turbolinksの原理までしっかり理解しようとすると正直難しいですが、大枠の仕組みをこの記事で掴んでいただけたらと思います。