View Transition APIについて調べてみた

Repro Boosterの開発を担当しているRyoma Shindo です。 今回はView Transition APIについて、基本的な使い方やCore Web Vitalsへの影響の有無など調査したのでご紹介します。

View Transition API とは

View Transition APIは、ページ遷移する際のアニメーションを手軽に実装するためのAPIです。MPA(Multi Page Application)/SPA(Single Page Application)どちらでも利用できますが、MPAで利用する場合、MPAでありながらSPAのようなスムーズな画面遷移を実現できます。 今回はMPAでの動作に焦点を当てて記載します。

最低限の使い方は簡単で、以下をCSSに追加するだけです。

@view-transition {
    navigation: auto;
}

適用すると、ページ遷移する際に画面全体がフェードアウト/フェードインするようになります。 これの原理としては、ページ遷移前後で対応する要素同士をアニメーションさせるのですが、デフォルトではHTML全体が対象なのでページ全体がアニメーションします。またデフォルトのアニメーションは、ページ遷移前の要素がフェードアウト、ページ遷移後の要素がフェードインに設定されているため、結果として上記の挙動となります。

ページ遷移前の要素には ::view-transition-old, ページ遷移後の要素には ::view-transition-new という疑似要素でアニメーションを設定できます。 デフォルトでフェードアウトが設定されているというのは、単にこういったアニメーションが適用されているということです。

@keyframes -ua-view-transition-fade-out {
  to {
    opacity: 0;
  }
}

ページ全体ではなく特定の要素をペアリングしたい場合は view-transition-name styleを利用します。

#main-image {
    view-transition-name: main-image-item;
}

このとき、このペアに対して ::view-transition-old(main-image-item) { ... } という指定でアニメーションを適用できます。 デフォルトでは、対応する要素の位置がなめらかに移動するアニメーションとなります。

遷移後の画面にペアとなる要素が存在しない場合はどうなるか

例えばペアとする要素がJSで動的に差し込まれる要素である場合など、ページ遷移した際にDOMが存在しない可能性があります。 その場合は、::view-transition-oldで指定した動作は行われ、::view-transition-newの動作は行われないという挙動になるようです。

デフォルトのアニメーションの場合だと、ページ遷移前の要素がその場でフェードアウトする形となります。 逆に、現在のページに要素が存在せず、遷移後のページに存在する場合は、::view-transition-new の動作が行われるのでページ遷移後の要素がフェードインで表示される形となります。

ちなみにこういった場合のために、linkタグのrel="expect"を利用して、必要な要素が準備できるまでページのレンダリングをブロックすることができるとのことです。

<link rel="expect" blocking="render" href="#section1">

...が、私が試した限りだとうまくrender blockingできているように見えなかったので、使い方がよく分かっていません。

Core Web Vitalsへの影響はあるか

結論、Core Web Vitals(+FCP)に与える影響はなさそうでした。

アニメーションがCLSとして判定されることはもちろんありませんし、LCPが早くなったり遅くなったりすることもないように見えました。 例えばanimation-delayを長めに設定して画面の変化が視覚的に遅れるようにしても、Core Web Vitalsの数値上は影響がないことが確認できました。これは、測定指標がユーザーの視覚的な体験ではなく、技術的なレンダリングの完了タイミングに基づいているからだと思われます。(ただし、前述のrender blockingを過度に使用した場合は、LCPに悪影響を与える可能性があります。)

ページ遷移時、View Transition APIによるアニメーションが発生していることを検知出来るか

ページ遷移前後でViewTransitionオブジェクトを操作できる pageswap, pagereveal イベントがあるようです。 TOPページ、一覧画面や詳細画面などページ種別によってアニメーションさせたい要素を切り替えたい場合などで利用できるとのことですが、これを完全にハンドリングするのは結構大変そうな印象なので、主要なページのみに絞って運用するのが現実的な落とし所でしょうか。

最後に

View Transition APIについて調査したことを記載しました。個人的にはCore Web Vitalsへの影響が気になっていたので、そこが確認出来て良かったです。 本気で使い倒そうとすると大変そうですが、まずは出来る範囲で使ってみてはいかがでしょうか。

Repro Boosterでは開発者を採用しています。「タグを入れる」だけでサイトを速くするRepro Boosterの技術に興味を持っていただけた方は、ぜひ気軽にご連絡ください。