Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第14章 Frames の失敗パターンと設計判断

この章のねらい

第11章から第13章で、Turbo Frames は強力だとわかりました。インライン編集も、遅延読み込みも、サイドバーも作れます。frame は入れ子にもできます。

しかし、強力だからこそ、使いすぎると複雑になります。この章では、「frame を使いすぎたときに現れる兆候」と、「そこで Turbo Streams や通常遷移へ切り替える判断」を学びます。これは第4部の締めであり、第5部 Turbo Streams への橋です。

この章では新しい機能は増やしません。代わりに、ここまで作ったものを振り返り、「どこまで frame でやるべきか」という設計判断の軸を持ちます。

14.1 frame の入れ子が深くなる兆候

第13章で、frame は入れ子にできると見ました。サイドバーの detail frame の中に、インライン編集の task_1 frame が入る、という形です。

入れ子は便利ですが、深くなると、自分でも追えなくなります。「このリンクをクリックすると、どの frame が差し替わるのか」が、すぐに答えられなくなったら危険信号です。

frame 内のリンクは、既定でいちばん内側の frame を差し替えます。data-turbo-frame で対象を変えれば、外側や別の frame も差し替えられます。入れ子が深いほど、この「どこが差し替わるか」の組み合わせが増え、予想とずれます。

対策は、入れ子を浅く保つこと、id を分かりやすく名づけること、そして「このリンクはこの frame」と説明できる範囲に留めることです。説明できなくなったら、設計を見直す合図です。

14.2 URL と画面状態のズレ

第11章で見たとおり、frame 内のリンクで遷移しても、ブラウザの URL は変わりません。これは部分更新の利点ですが、行きすぎると問題になります。

たとえば、サイドバーであるタスクの詳細を開いた状態で、ページをリロードしたとします。URL は一覧のままなので、リロードすると詳細は閉じ、最初の状態に戻ります。URL を誰かに共有しても、相手の画面に同じ詳細は出ません。戻るボタンの挙動も、ユーザーの期待とずれがちです。

つまり、いま見えている画面の状態が、URL から復元できない状態です。これは、frame で作り込むほど起きやすくなります。

その画面の状態を URL に残したいときは、frame の遷移を「URL も進める visit」に格上げします。リンクに data-turbo-action="advance" を付けます。

<%= link_to task.title, task_path(task),
      data: { turbo_frame: "detail", turbo_action: "advance" } %>

こうすると、frame を差し替えつつ、ブラウザの URL も更新されます。リロードや共有に耐える画面になります。逆に言えば、「URL に残すべき主要な画面か、残さなくてよい補助的な部分か」を意識して、frame を使い分ける必要があります。

14.3 controller が frame 分岐だらけになる兆候

frame を増やすと、controller 側にも影響が出ます。「通常のリクエストのときはページ全体、frame からのリクエストのときは frame の中身だけ」と返し分けたくなり、リクエストの種類で分岐するコードが増えていきます。

controller のアクションが、リクエストが frame からかどうかで if 分岐だらけになってきたら、それは兆候です。多くの場合、同じビューの中に frame を置いておけば、Turbo が必要な frame だけを取り出してくれます。まずは、リクエストの種類で分岐を増やさずに済まないかを考えます。

分岐が増えてきたら、まず「同じビューを返して Turbo に任せられないか」を考えます。それでも複雑なら、次の 2 つの判断に進みます。

14.4 Streams へ切り替える判断

frame には、はっきりした限界があります。1 回の frame navigation で Turbo が差し替える対象は、1 つの frame だけです(frame の中にある複数の要素は、その frame ごとまとめて差し替わります)。

たとえば、タスクを 1 件削除したときに、離れた場所を同時に更新したいとします。

  • 一覧から、その行を消す
  • 「残り 12 件」という件数表示を更新する
  • 「削除しました」というフラッシュを出す

これは、互いに離れた 3 か所の更新です。1 回の操作で差し替えられる frame は 1 つだけなので、frame だけではこの要求に応えられません。ここが、Turbo Frames から Turbo Streams へ切り替える判断点です。

第7部で使う判断軸を先取りすると、「更新する場所が 1 か所なら Turbo Frames、複数を同時に更新するなら Turbo Streams」です。複数箇所の同時更新が必要になったら、frame で粘らず、Streams へ移ります。これが、次の第5部のテーマです。

14.5 通常遷移に戻す判断

独立した部分更新の要否と更新箇所数で、通常遷移・Frame・Streams を選ぶフローチャート。

もう 1 つの判断は、逆方向です。そもそも部分更新が要らないなら、frame をやめて通常の遷移に戻す、という判断です。

frame は、「ページの一部を、周りと独立して差し替えたい」ときに価値があります。逆に、ページ全体が変わるような画面遷移(一覧から詳細へ完全に移動する、など)では、frame の独立性は要りません。それなのに frame で作ると、14.2 の URL のズレや、14.1 の入れ子の複雑さだけを抱え込みます。

「URL の問題に悩んでいる」「frame の入れ子と格闘している」けれど、その画面は本当は普通のページでよかった、という場合があります。そのときは、frame を外し、第3部で見た Turbo Drive の通常遷移に戻すのが正解です。Turbo Drive なら、ページ遷移は十分速く、URL も素直に変わります。

判断の基準は、「できるか」ではなく「読みやすく保てるか」です。frame でできるとしても、通常遷移の方が素直なら、そちらを選びます。

第4部では、Turbo Frames を「独立した小さな visit 領域」として学び、その使いどころと、使いすぎの見切りまで見ました。14.4 で触れたとおり、複数箇所を同時に更新したくなったら、次の道具が要ります。第5部では、その Turbo Streams を学びます。

参考資料