todo-add-alt

話題の Portals を使った画面遷移 UX の未来

滑らかなページ ナビゲーションも積極的に取り組みたい 2019 年

Mar 19, 2019

🔥 ちょっともう内容が古いです。最新は web.devWICG Explainer を確認されることをおすすめします。

ご無沙汰しております。ウェブボウズを立ち上げて 1 年が経ちました。皆さま如何お過ごしでしょうか。私は、この 1 年間ひとつもブログポストできていません。さらには私の坊主頭(スキンヘッド)にちなんでウェブボウズという名前をつけた個人ブログでありましたが、5 年間共にしたこの Hair-less style から心機一転して 2019 年は髪を育んでいく方針を固めましたので、もはやボウズでもなくなってます。変わり続けることだけが普遍であると胸に刻んで今年も強く生きていきたいと考えております。

さて、最近 Signed HTTP Exchanges やら Performance Budget やらさまざまな面白いことに関わらせていただいて忙殺と幸せを噛み締めている中でも、Chrome Dev Summit 2019 でも大きくフィーチャーされました Portals という新しい HTML 要素が好きで、いろいろデモ作ったりなんだりしていまして、本当に面白いのでここらでいっぺん私が学習した内容をまとめて、ひとりでも多くの方に興味を持ってもらえるようこの場に共有したいと思います。

いままでの Web は

ページスピードの重要性はここ数年で認知されてきているかとは思うのですが、あくまで単体のページがステートレスな状態でどこまで速く表示されるか、という点が注目されがちで、RAIL でいうところので L(Load)以外の R(Responsiveness)A(Animation)I(Idle)に関してはあまり議論されていないように感じます。初期表示はもちろん大事ですが、勝負はページが表示されてからです。気持ちよくユーザーがサイト内回遊できるような、そんな UX を考える必要があります。

そういう意味で SPA っていいと思うのです。App Shell モデルもしかりですが、常に画面上に表示され続けるヘッダーやフッターはそのままに、ナビゲーションするとコンテンツだけが切り替わっていくので、アプリケーションとしての文脈は持続されます。一方で MPA(=マルチ ページ アーキテクチャ。かっこよく言っていますが、要するに URL 単位に個別のページが存在するごく普通の構成のことです。)だとページ ナビゲーション時の一瞬の真っ白な画面とか、やっぱりちょっとなんとかしたいものです。この対策としてデベロッパーの皆さまは Prefetch を活用したり、ブラウザ側も back / forward cache(先日Chromeでも実装中であることが公開されましたね)を実装したり、なんとか滑らかなナビゲーションを実現しようと腐心されているものと思います。頭が下がります。

じゃあ Portals は何をしてくれるか

でも SPA 作れと言われてもフレームワークに明るいメンバーがいなかったり、そもそも既存のサイトがあったり、それを全部更改するには時間とお金がかかったり、あれ SPA にしたらちゃんと検索エンジンに Index されるんでしたっけ?という質問がビジネスサイドから来たり、じゃー SSR しましょうかと新たな Rendertron サーバー インスタンス立ち上げに苦労したり、そういうさまざまな理由で SPA に手を出せていないデベロッパーの皆さまも少なからずいるのではないかと想像します。私も React とか Vue 流行ってるしかっこいいしすごくその界隈に混ざりたいのですが、日々の業務に追われてなかなかキャッチアップできていません。

一方でそんな多忙で制限のあるデベロッパーの皆さまも、iframe は少なくとも一度は使ったことがあると思うのです。<iframe> タグを書いて、その src 属性に表示したい URL をいれると、不思議と別ページを任意のページに埋め込めるアレです。簡単に表現すると、そんな iframe に表示しているページに直接ナビゲートできるのが Portals となります。百聞は一見にしかずなのでまずこちらの動画(18:05 から)をご確認頂ければと思います。


Before では、マンガのとあるチャプターを読み終わって次のチャプターに移ろうとした際に、皆さまが毎日体験されるクラシックな「ページ ナビゲーション」が発生していることがわかるかと思います。それに対して After では次のチャプターをあらかじめ表示し、ユーザーのインタラクションに応じてその表示済のコンテンツに実際にナビゲートできています。これ、アドレスバーが表示されていませんが、左下に表示されていた次ページが全画面を覆うタイミングで URL もしっかり変わっています。

iframe では別ページを表示するところまではできました。さらには CSS Transition などでアニメーションを加えることもできるかと思います。でもこのように実際のその表示コンテンツにナビゲートすることはできません。Portals はこれを実現します。

試してみよう as of Version 75.0.3734.0 (Official Build) canary (64-bit)


現状 Chrome Canary で Portal は試せます。起動フラグを付けて Canary を立ち上げてください。
  • Mac: open -a Google\ Chrome\ Canary --args --enable-features=Portals
  • Windows: ショートカットを右クリック、リンク先に --args -enable-features=Portals のオプションを付けて起動。
  • Linux: Canary は Linux ではサポートされていません。代替として Chromium をご利用ください。
続いて、DevTools の Console を開いて HTMLPortalElement が存在することを確認しましょう。

todo-add-alt

それでは、サンプルコードで具体的に見ていきましょう。


ものすごい簡単です。ぜひ Console でこれを叩いてみてください。Wikipedia が開くはずです。これを応用して Chrome Dev Summit で紹介されていたデモのような動きを実現したければ例えばこのような実装も考えられます(殴り書きなのでご容赦を)。

todo-add-alt


こちらは、たまたま Custom Element で実装してみましたが、別に Web Component に拘る必要はありません。iframe を扱うかのようにお好きな方法で操作してみてください。

ちなみにちゃんと Feature detection もできます。HTML Element なのでこんな感じでしょうか。


(Portal を利用するにあたっては、いずれせよ activate をコールしないといけないので、JavaScript は必須になります。その意味で上記の Feature detection は確実ですが、Picture タグ内のフォールバック img のように HTML Element として対応する可能性もあるかも?

これで Progressive Enhancement することも可能です!すぐに使える!!

...という感じでこの記事を書いていたのですが、簡単に試せるデモ ページがあったほうがいいかなと思いまして急遽簡易的ではありますが、uskay-portals-demo.glitch.me を用意しました。Portal として表示したいページの URL を入力いただき、Embed Portal Element ボタンを押下するとそのページが Portal として表示されるように作ってあります。そして、表示された Portal をクリックすると、アニメーションが走った後に activate されます。Portals 非対応ブラウザの場合は Feature detect してその旨表示します。

todo-add-alt

ぜひともお試し下さい。

スペックを確認してみよう

現状 WICG にてスペックの議論がされています。詳しくはこちらをご確認頂ければと思いますが、大きく分けて以下の 3 つのインターフェースが検討されています。
  • The portal element: HTML Element 自体。API は非常にシンプルで、activate 関数とメッセージをやり取りするためのインターフェース(postMessage, onMessage等)が準備されています。activate 関数には引数でオプションを指定可能で、activate するページにイベントを通じて任意のデータを渡すことができます。
  • The portal host interface: window.portalHost を公開し、自身が Portal として利用されているかの判定が可能になります。また、メッセージをやり取りするためのインターフェース(postMessage, onMessageなど)が準備されています。
  • The PortalActivateEvent interface: 自身が activate されたことを受け取るイベントです。非常に面白いのが、このイベントには adoptPredecessor という関数が用意されておいて、以前のページを Portal オブジェクトとして受け取れます。Portal を使ったページの行き来に便利!
他にも、Portal element は iframe と異なり Unit of related browsing contexts として扱われるため(UA まかせですが)個別の Event Loop を持つこともできる、など興味深い仕様があるので、ぜひとも一度スペックを読まれることをおすすめします。

想定されるユースケースと今後の展開

如何でしょう。けっこう気軽に始められるページ ナビゲーション最適化ではないでしょうか。例えば「商品一覧ページで、ナビゲートする可能性が高い商品ページをあらかじめ Portals で読み込んでおき、ユーザー インタラクションに応じて activate する」ようなユースケースが真っ先に思いつきますが、もうひとつ大事なポイントは Portals は cross-origin のページも扱えるので、複数オリジンのハブになるようなサイトをお持ちの場合にも適用できます。特にこの cross-origin のユースケースは、現状だと SPA でも実現は難しいものと思いますので、いままでになかった新たな表現を Web にもたらします。

ただ、まだアーリーなフィーチャーなので、現時点では当然完璧ではありません :
  • activate すると session history が全部なくなってしまったり(元のページに戻れない!)
  • postMessage によるやり取りがまだできなかったり(Portal のレンダリングが終わったことの通知してから画面上に表示させたい!)
  • adoptPredecessor などまだ実装されてない機能があったり(もっとクリエイティブな使い方をしたい!)
  • DevTools とのサポートがまだまだだったり(Portals 内のログが Console で見づらい)
など。こちらを見るとそれぞれの対応状況がわかります。

また、前述したとおり現状 WICG で話が進んでおり、W3C 上だと Working Draft もこれからですので、Chrome で Trial をはじめてユーザー・デベロッパーからのフィードバックを得ながら同時並行で仕様を固めに行く方針でしょうか。その意味でも、ぜひとも一度 Chrome Canary で遊んでみて頂き、何か問題や、改善点などありましたら、 仕様に関するものであれば WICG へ、Chrome の問題であればバグを起票するのがよいかと思います。

さいごに

Web Packaging といい、この Portals といい、いままでの Web をダイナミックに変えていく仕様が増えていくことにワクワクするのと同時に、日々の業務に追われてなかなかこういう情報に関してブログポストできていませんでしたが、今年はより頻繁に更新していきたい所存ですので、お時間あるときにでもこっそり訪問いただければと思います。

そのころにはまた私の髪型も変わっているかもしれませんが。


$whoami

Yusuke Utsunomiya (宇都宮 佑亮). Working on the Web Platform but mostly just a big fan of the web and its ecosystem. APAC Manager & Staff Partner Solutions Engineer @Google. Ex Systems Engineer @IBM. Opinions are my own.

Presentation

Article