· 5分で読了

HotwireとTurbolinks

この記事は中国語から自動翻訳されたものです。翻訳によりニュアンスが失われている場合があります。

はじめに

DHH(Ruby on Railsの生みの親)が新作のHotwireについてツイートした。DHHはSPAのアンチ(ツイートからも察しがつく)であり、開発においてJavaScriptを多く導入することを極力避けている。このツイートはTwitter上で熱い議論を巻き起こしたので、ここで僕なりに少し整理してみる。

Hotwireの紹介については、公式の説明をそのまま引用する。

Hotwire is an alternative approach to building modern web applications without using much JavaScript by sending HTML instead of JSON over the wire

この説明には2つのポイントがある。

  • JavaScriptをあまり使わない
  • JSONではなくHTMLを直接送信する

この概念は実は最近現れたものではなく、何年も前からRuby on RailsはTurbolinksと呼ばれる類似の手法を採用していた。

Turbolinksとは何か?

TurbolinksはJavaScriptパッケージであり、通常はRuby on Railsと一緒に使われる(単体のライブラリとして使うことも可能だ)。主にHTMLをfetchして直接差し替える手法によって、通常のページ遷移に伴う再リクエストやCSSのコストを回避する。「JavaScriptを使う必要がない」と言うのは厳密には正しくない。JavaScript自体は存在しており、ライブラリ側ですでに処理してくれているため、開発時にJavaScriptを書かなくて済むというだけのことだ。

例えば、ページ上にこのようなタグがあるとする。

<a href="/articles/1" data-remote="true">link</a>

Ruby on RailsでTurbolinksの機能を有効にしている場合、ユーザーがリンクをクリックした時、実際にはリクエストを再送信するのではなく、Turbolinksが次のような処理を行う。

fetch('/index.html').then(res => res.html())
	.then((html) => $page.html(html))

こうすることで、ユーザーがボタンをクリックした際、HTMLが最初から再レンダリングされるのではなく、まずそのページのHTMLファイルを(Ajax経由で)fetchし、JavaScript経由で直接レンダリングする。Ruby on Rails自体がTurbolinksと高度に統合されているため、時にはTurbolinksの存在をほとんど意識することなく、「あれ、なんだかページ遷移が速くなったぞ」と感じるだけになる。

HTMLが大きくなるにつれて効果は薄れていくだろうが、HTML自体が大きくない場合は、より良いユーザー体験を実現できる。

なぜこの手法が効果的なのか?

  • ページ遷移でCSSやJavaScriptを再リクエストする必要がなく、ユーザー体験が向上する
  • head部分はTurbolinksが自動で処理してくれる
  • 追加のJavaScriptを書く必要がほとんどない
  • バックエンドエンジニアが最小限の労力でより良い体験を提供できる

注意すべき点

  • load のようなイベントは、Turbolinksの仕組み上ページ全体が再読み込みされないため、初回読み込み時しかトリガーされない。turbolinks:load などのイベントリスナーに切り替えることを覚えておく必要がある
  • JavaScriptのインタラクションが増えるにつれて、イベントリスナー同士が衝突しやすくなる
  • ページ遷移時に状態が破棄されないため、JavaScriptの書き方が悪いとメモリリークを引き起こしやすい

JavaScriptのインタラクションが増えるにつれて、Turbolinksと組み合わせた際に多重実行によるエラーなど、奇妙な現象が発生することがある。

僕の考え

開発者として多かれ少なかれSPAを書いた経験があるため、実用に耐えうる使い勝手の良いSPAを作るのが容易ではないことは誰もが知っているはずだ。状態管理がうまくいかずにメモリを大量消費したり、状態が非同期になったり、エラー処理が不十分だったり、何かにつけて巨大なJavaScriptバンドルを読み込んだりしてしまう。それならいっそ純粋なSSRによるレンダリングにして、Turbolinksのような仕組みで体験を向上させる方が、むしろ良いアプローチかもしれないと僕は思う。

あとがき

JSONはHTMLよりもサイズが小さいため転送効率が良いと考える人もいるが、gzip圧縮後では実際両者は大差なく、時にはHTMLの方が小さいことすらある。だからHTMLを直接レンダリングすることは、決してそれほど許されない罪というわけではないと感じる。

ただ、現状Turbolinksとの統合が最も優れているのはおそらくRuby on Railsだけであり、Hotwireはまだ比較的新しいため、様子見をしている開発者もいるかもしれない。

関連記事

他のトピックを探索