【rails】いつも邪魔してくるturbolinksとはなんぞや


こんばんは、たにーです。

最近チーム開発と色々やることが多くなかなか書けずに、、、
とりあえず今日時点まで学んだことを振り返りながら記事にしていきます。

今日は、タイトルの通り、

「turbolinks」とはなんぞや

です。

RubyのフレームワークであるRuby on Railsを使ったことがある人なら
恐らく、こやつ(turbolinks)のせいで、上手く動かない、反応しないなどの経験があると思います。
私自身も経験があり、turbolinksに邪魔されてきた初学者です。泣

だだ、私自身こやつのことを何にもわかっていません。
なので、今回は、tubolinksの正体?機能?必要?不必要?について
書いてきますのでよろしくお願いします。

そもそものturbolinksって?

Asset Pipeline を活用しているアプリケーションにおいて画面遷移を高速化するライブラリです。

、、、僕はいまいちピンと来ず理解できません。

なので、分解します。

Asset Pipelineとは

複数のディレクトリやファイルに分かれたassetsディレクトリ内のファイルをひとつに連結・圧縮する機能です。

Rilsでは、HTMLファイルは、viewのディレクトリあるが、
CSSは、assets/stylesheetディレクトに、imageもassets/imagesディレクトにと分けています。
これは、開発者にとっては、何がどこにあるのかをわかりやすく認識させるためです。

WEBブラウザにはそれらの複数のファイルを結合して表示する、などの機能はありません。
そのため、別々のディレクトリで複数分けてしまうと、それぞれが別のファイルとしてあるため、WEBページとして扱うことが不可になる。

そのために考え出されたのが、AsserPipelineである。

ひとつのファイルに連結・圧縮され、erbテンプレートからHTML化されたファイルとひも付いてからWebブラウザ画面上に表示されるようになります。この仕組みによって、Webアプリケーション内への効率的にアクセスすることもできます。

*参考文献の画像を引用。

画面遷移とは

リンクや投稿して、別のページに移動する。つまり、今いる画面から他の画面に移動することを示す。
link_toでのリンクや、redirect_toなどで移動するのが、画面遷移かなと。

ライブラリとは

ライブラリとは、汎用性の高いプログラムを再利用できる形でまとめたものを意味する。
Gemがそのことを言うと思います。ログイン機能を簡単に実装できる、「revise」や、画像使用/投稿を可能にする「refile」などなどRailsには多くのGemがあります。

なるほど、、、
これだけ分解したら個人的には理解できた気がします。

より具体的に説明すると、

turbolinksは、リンクのクリックイベントをフックし、Ajaxリクエストに変換します。
そしてレスポンス(新しいページの HTML)を受け取ると、現在のページのtitle/bodyを新しいHTMLのtitle/bodyに交換します。
こうすることで、head内で参照されるスタイルシートやJavascriptをブラウザが取得しなおす処理をスキップすることができます。また、History API を用いてコンテンツのキャッシュやブラウザ履歴の操作が行われるため、ブラウザの戻るボタンが押されたときにも違和感無く前のページの内容が復元されます。

こうみると、turbolinksは、邪魔というよりwebページを表示する上で大きく手助けしている。

でも、注意点がいくつかある。

  • Turbolinks はデフォルトで(プロジェクト生成時点で)有効になっている。
  • Turbolinks を導入すると Javascript のイベント発生タイミングが異なる。

調べると、 Javascript のイベント発生タイミングの違いが皆さんの邪魔をしているポイントになってそう。

javascriptを書いてある人なら恐らく下記の記述をしたことがあるかと。

application.js
$(function(){     .....   });

私は、郵便番号による住所自動反映や非同期通信、jQueryなどを使用した際にjsファイルを書くので
恐らくそのとき上手くいかなかったのは、これが原因だったんだとわかりました。

JavaScriptは、ページがより込まれたタイミングでloadイベント(jsファイルが実行する)が起きるが、
turolinksによって、画面が切り替わってもその通常起こりうるloadイベント(jsファイルが実行されない)が起きなくなってしまう。

結論としては

turbolinksは、

全体的な通信量の削減を可能にする反面、JavaScriptの動きを阻害してしまう。

ライブラリでした。

webページにおいて、通信量の削減で大きく貢献しているturbolinksですが、
JavaScriptを使用した動きのあるサイトを作る際には、使い方を考える必要がありそうです、、、、。

最後に、私自身が調べて実際に使用した turbolinks対策です。

部分的にturbolinksを無効化する方法

方法としては、2つあると思います。

①turboliknsを使用しない設定(gemや記述を取り除く)

Gemfile
gem 'rails', '~> 5.2.4'
gem 'sqlite3'
.
.
gem 'turbolinks', '~> 5'    => を削除する。
app/assets/javascripts/application.js

//= require jquery3
.
.
//= require jquery.jpostal
//= require turbolinks       => を削除する。



②data-no-turbolink 属性を付ける。
私は、これを実際に使用しました。

application.rb
  #(1) 特定のリンクのみ Turbolinks を無効化する
  <a href="#" data-no-turbolink>.</a>

  #(2) 特定の範囲で Turbolinks を無効化する
  <div data-no-turbolink>
    <a href="#">...</a> 
  </div>

  #railsの場合
  <%= link_to "一覧画面へ", root_path, data: {"turbolinks" => false} %>

これで動くと思います。
もっと調べることもできますが、今は一旦ここまで理解しておけばいいかなと。

これからも疑問点は調べてQiitaに投稿するようにします。

以上、たにーでした。

参考文献

*最後の補足に記載があります。