『Turbolinks』って、なんぞ?

f:id:ryoutaku_jo:20190115212246p:plain

【結論】
・Turbolinksとは、画面遷移を高速化させるライブラリ
・「rails new」した時点から、標準で組み込まれている
・これが原因で、Javascriptが正常に機能しなくなる場合がある
・組み込みライブラリなので、仕様は必ず把握する必要がある


【目次】


【本題】

調べるきっかけ

『Turbolinks』という物に興味が湧いたので、
今回はそれを調べることにしました。

きっかけは、アプリを作成している際、
Javascriptが機能しないエラーが発生し、
同期の中でもトップクラスのスキル持ちの方に相談したところ、


「それ『Turbolinks』が原因かもしれない」


と言われたことです。

スクールのカリキュラムに出て来ない内容だったので、
全く理解出来ず、その時は言われるまま対応したのですが、
理解していない状態で放置しておくのはマズイと感じたので、
調べることにしました。

『Turbolinks』とは

画面遷移を高速化させるライブラリです。
rails new」した時点から、標準で組み込まれています。
「asset pipeline」というフレームワークの一部です。

高速になる理由は、画面全体を更新するのではなく、
画面の一部だけを更新させているからです。

具体的な仕組み

詳しい仕組みを見ていきます。

まず、ブラウザがページを表示するとき、通常は下記の様な流れで通信します。
1:ページ自体の HTML をダウンロードする。
2:ページの中で参照されているスタイルシートJavascript をダウンロードする。
3:ページをレンダリングする。

この「2」の段階で、スタイルシートJavascript が複数存在すると、
ブラウザと Web サーバの間で複数の通信が行われ
、通信速度に影響を及ぼします。

そこで登場したのが、
「asset pipeline」というフレームワークです。

Rails3.0から登場した「asset pipeline」は、
複数のスタイルシートJavascriptを一つのファイルにまとめることが出来るので、
それによりブラウザとサーバ間の通信が抑えられました。

そして、Rails4.0から「asset pipeline」に
新たに追加された機能が、「Turbolinks」です。

「Turbolinks」は、ページを遷移する際に、
現在のページの [title] と [body] だけを抜き取って、
新しい HTML の [title]と [body] に交換します。

こうすることで、 内で参照されるスタイルシート
Javascript をブラウザが取得しなおす処理をスキップし、
更に通信を抑えることが出来る様になったのです。


注意点

ページ読み込みを起点としたJavascriptは機能しなくなる

通常であればページが読み込まれたタイミングで load イベントが発生しますが、
Turbolinks によって画面が切り替わった場合は load イベントは発生しません。

その為、ページ読み込みを起点としたJavascriptは機能しなくなります。

例えば、jQuery を使用している場合、
下記の様にページが読み込まれたときの処理を記述出来ますが、
Turbolinksによって、実行されなくなります。

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

その他にも、jQuery.ready や DOMContentLoaded を使用しても、
ページ切り替え時にそのイベントは発生しません。

load イベントを発生させたい場合は、
Turbolinksを無効化させる必要があります。


直接アクセスされた場合は、Turbolinksが発動しない

リンクを経ずに直接ページにアクセスされた場合や、
ブラウザで再読み込みを行なった場合は、Turbolinksが発動せず、
通常通り、ページの読み込みが行われます。

但し、リンクを経ると、Turbolinksが発動するので、
どちらの場合でも処理を実行したい場合は、
Turbolinksを無効化させるか、下記の様に両方に対応した記述をする必要があります。

// 画面が切り替わった場合に行う処理.
var handler = function() {
    alert("画面が切り替わりました");
}

// 普通に画面が読み込まれた場合.
$(handler);

// Turbolinks によって画面が切り替わった場合.
$(document).bind("page:load", handler);

// ブラウザの戻るボタンで画面が切り替わった場合にも処理を行いたければ page:restore にも設定する.
$(document).bind("page:restore", handler);


別のスタイルシート/Javascriptを参照している場合は、効果が無い

ページごとに違いスタイルシートなどを参照している場合、
ページ遷移を高速化させる力を発揮することが出来ません。
(「head」を読み込み直す必要があるので、通常と変わらない)



部分的に無効化させる方法

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

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

全体で無効にする方法

1:Gemfile から「gem ’turbolinks’」を削除する。
2:app/assets/javascripts/application.js から「//= require turbolinks」を削除する。
3:app/views/layouts/application.html.erb の
 javascript_include_tag や stylesheet_link_tag から
 「"data-turbolinks-track" => true」を削除する。


総括

まだ恩恵を預かれるほどのリッチなアプリは作っていないですが、
特にこちらで用意しなくても、Ajaxが簡単に実装できるという事で、
非常に便利な機能だと感じました。

本当にRailsはこういった機能が標準で付いていて、
便利な反面、これらの存在を知らないと、
理解出来ない様なエラーに遭遇したりするので、
それが難点ですね・・・

このライブラリ周りについては、進んで情報収集する必要があると感じました。

《今日の学習進捗》

スクールのアプリに、
JavaScript, jQueryを用いた非同期通信の実装完了
これでアプリは一先ず完成!

正直Javascriptの基礎が定着しているとは言えない状態だったが、
作って調べる内に、自然と仕組みを理解することが出来た。

やはり技術書や解説をひたすら読んで基礎を固めるより、
少し難しめでも実際に手を動かし、自分で考えて作った方が、
スキルとして定着するのだと、改めて実感した。

そして、最近モチベーションが非常に高い!!!!!
どんどんスキルが身に付いている実感があるからだと思う。

学習開始からの期間 :39日
今日までの合計時間:388h
今日までに到達すべき目標時間:356h
目標との解離:32h
「10,000時間」まで、

残り・・・「9612時間!」