Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Rails: Turbo 8ではリンクにマウスオーバーするとデフォルトでprefetchが送信される

Rails 7.2.beta3でいろいろ試していたときに、scaffold + Tailwindで生成されたリンク(Tailwindによってボタン風のスタイルになっています)にマウスオーバーするだけでリクエストが送信されていることに気づきました。様子がよくわからなかったので、このあたりを調べてみました。

念のため、Tailwindを使わない素のRails 7.2.beta3でもscaffoldして試してみましたが、同様にボタンへのマウスオーバーでリクエストが発生していましたので、Tailwindは無関係でした。

Turboのprefetch

結論から言うと、これはTurbo 8で導入された挙動だそうです(#1101)。以下のStack Overflowエントリで知りました。

参考: Rails with Hotwire/Turbo doing get requests on link hover - Stack Overflow

Turboのprefetchの目的

以下のInstantClickというリンク高速化用のJavaScriptライブラリと同様の振る舞いを得る形で、リンクのクリックのレスポンスを改善するためだそうです。

dieulot/instantclick - GitHub

リンクをユーザーがマウスオーバーすると、クリック前にリンク先をプリフェッチします。

プリフェッチを止める方法

リンクのプリフェッチをグローバルに止めたい場合は以下のmetaタグを追加します。自分のRailsアプリではプリフェッチは不要だったので、これを使いました。

<!-- app/views/layouts/application.html.erb -->
<meta name="turbo-prefetch" content="false">

個別のHTML要素で無効にしたい場合は、data-turbo-prefetch="false"属性を個別に追加します。

<a href="/" data-turbo-prefetch="false">Home</a>

<div data-turbo-prefetch="false">
  <a href="/">Home</a>
  ...
</div>

おまけ

なお、data-turbo-preloadが既にあったこともあり、議論の末にプリロードではなくプリフェッチという名前にしたそうです。

#1101のプルリクメッセージを見ると、当初はデフォルトでプリフェッチを無効にしていたようですが、Turboのドキュメントを見ると、最終的にTurbo V8からデフォルトで有効にすることになりました(#1162)。

この#1162のプルリクメッセージに以下が書かれていたのでメモします。

古いアプリを(Turbo 8に)移行しやすくするため、data-remotedata-behaviordata-methoddata-confirm属性を持つリンクタグについてはプリフェッチを行わないようにしている(これらの属性は、古いアプリのUJSで安全でない振る舞いをトリガーするのに使われている)。
モダンなアプリは<button>タグで実装する傾向がある。
#1162より

関連記事

Railsフロントエンド: HotwireとTailwind CSSでモーダルを作る(翻訳)

Railsフロントエンド: ViewComponent+Tailwind CSS+Hotwireの便利技8つ(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。