ナビゲーション
従来のフルページ遷移には、ドキュメントが切り替わるときの白い点滅と、操作の流れを 止める待ち時間がありました。シングルページアプリケーションはこの 2 つを避けましたが、 いまでは唯一の選択肢ではありません。
ビュートランジションと Speculation Rules は、ハンドラやレスポンスを変えずに、 ブラウザ側でこの問題を軽減します。未対応のブラウザでも、通常のページ遷移として そのまま動きます。
ページ間の連続性
Section titled “ページ間の連続性”両方のページが読み込むスタイルシートに 1 行足します。
@view-transition { navigation: auto }同一オリジンの遷移が、切り替わりではなくクロスフェードになります。設定はこれで 全部で、費用は宣言 1 つです。
この規則はコンポーネントのスコープ付き <head> ブロックをそのまま通り抜けます
—— スコープすべきセレクタを持たない at-rule だからです —— が、本来の置き場は共有の
スタイルシートかドキュメントシェルです。遷移は 1 つのコンポーネントではなくサイトの
性質だからです。
要素に名前を与えると、フェードではなく移動します。両方のページで概念的に同じもの
—— 一覧のサムネイルと詳細ページのヘッダ画像 —— に同じ view-transition-name を
与えてください。
<head><style>.hero { view-transition-name: task-hero }@media (prefers-reduced-motion: reduce) { :global(::view-transition-group(*)) { animation: none }}</style></head>view-transition-name は、遷移が始まる時点でドキュメント内で一意でなければ
なりません。リストではつまり、名前はすべての行ではなく遷移先になる項目のもの
です。クリックされた行に付けるか、行ごとに別の名前を付けてください。
ドキュメント間のビュートランジションはまだ全エンジンにはありません。ない環境では 遷移はこれまでどおり起きます。早い段階で入れて安全なのはそのためです。
すでに終わっているナビゲーション
Section titled “すでに終わっているナビゲーション”Speculation Rules は、クリックの前にページを取得する —— あるいは完全に描画する —— ようブラウザに伝えます。置き場はドキュメントシェルで、JSON はそのまま書けます。
package templates
export component Document(children: html?): html {<!doctype html><html lang="ja"><head> <meta charset="utf-8"> <title>My App</title> <script type="speculationrules"> {"prerender": [{"where": {"href_matches": "/tasks/*"}, "eagerness": "moderate"}]} </script></head><body><slot /></body></html>}スクリプト内の中括弧は、テンプレートの挿入として読めない限りリテラルです。ルールの ブロックがそう読まれることはありません。読まれてしまう例は ブラウザ標準の部品にあります。
インラインスクリプト自体を避ける手もあります。レスポンスヘッダでルールを指し示す
やり方で、厳しい script-src ポリシーが好むのもこちらです。
Speculation-Rules: "/speculation-rules"このルートは application/speculationrules+json で答える必要があるため、
public/ に置いたファイル(メディアタイプが拡張子から決まります)ではなく、小さな
ハンドラになります。
| eagerness | 発火 | 用途 |
|---|---|---|
conservative |
ポインタ/タッチのダウン | 生成コストの高いもの |
moderate |
200ms 程度のホバー | 普通の詳細ページ |
eager |
ルールを見つけた時点 | 次に来る可能性が高い、小さく既知の集合 |
prerender の代わりに prefetch を使うと、描画せずにドキュメントだけ取得します。
安く、弱く、大きなサイトの既定として妥当です。
href_matches のパターンを広げる前に、あと 2 つ知っておく価値があります。
- 訪問されなかった prerender も、サーバーの描画 1 回分を消費しています。すべてでは なく、読み手が実際に次へ進むルートに合わせてください。
- サーバー側の描画を訪問として数える計測は過大になります。
document.prerenderingとprerenderingchangeイベントで、クライアント側の計測を activation まで待たせら れます。
Speculation Rules は今日のところ Chromium の機能です。他ではブロックが無視されます。
そもそも遷移しない
Section titled “そもそも遷移しない”フラグメントの swap は遷移なしに領域を差し替えます。URL は変わらず、履歴も増えず、 戻るボタンが返る先もありません。それは扱う状態しだいで、まさに正しいか、静かに 間違っているかのどちらかです。
| その状態が | 選ぶのは | 理由 |
|---|---|---|
| 共有・ブックマーク・再訪の対象になる | 遷移 | それを運べるのは URL だけ |
| 読み手が 10 回作り直す絞り込み | swap | 履歴 10 件は、戻るボタンにとって 10 個の誤答 |
| 読み手が離脱しうるフローの一段 | 遷移 | 離脱できることが要件 |
| 一覧の隣の詳細パネル | swap、リンク可能なら URL にも反映 | 両方の性質が欲しい |
クラシックな答えが正しいことは多くあります。普通に送信する絞り込みフォームは、 共有できる URL と、機能する戻るボタンと、正しい空状態を無料でくれます。その代償の 往復 1 回は、prerender がすでに払い終えているかもしれません。
swap が必要な場合でも、URL の管理は自分の手に残ります。history.pushState か、
ドキュメントシェルが読み込んでいる swap ライブラリの対応する属性です。フレーム
ワークはここに関与しません —— マークアップとステータスで答えるだけで、フラグメントの
レスポンスには URL を説明するものが何もありません。
スクロールと Post/Redirect/Get
Section titled “スクロールと Post/Redirect/Get”POST に 303 See Other と Location で答える形は書き込みの正解であり続けますし、
ここまでの話とよく噛み合います。リダイレクト先は普通の GET なので、prerender
できて、トランジションの対象にでき、再送信なしに再訪できます。
読み手をどこへ着地させるかは実際の判断です。いま編集した行のフラグメント識別子を 付けて一覧へ戻せば、スクロール復元のコードなしに元の位置が保たれます。
