アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

Chrome Dev Summitで披露された高速化のテクニックの数々(所感を含む)

f:id:masahirotanaka:20181119134014p:plain

こちらのブログではご無沙汰しています。田中です。今週はサンフランシスコにて開催されたChrome Dev Summitに参加させていただいていました。今年はweb.devの発表や新しいPageSpeed Insightsなど、例年にも増して盛りだくさんの発表が行われましたが、特に「スピードの改善テクニック」が数多く披露されたように思います。

Chrome Dev Summitのプレゼンテーションはすべて濃厚で、しかも多くの内容は「web.dev」に詳しく説明されています。ここでは、2日間にわたって行われたセッションを振り返りながら、高速化に関する内容をざっくりと追っていきたいと思います。

V8エンジンの改良

  • 以前と比べて、WebサイトのJavaScriptコード量は8倍に膨れ上がっている
  • V8の言語機能を今後も最適化していく:Promise、Async & await、フレームワーク対応等
  • ReactのHooks機能をV8で最適化できるように
  • WASM(Web Assembly)のコンパイラー「Liftoff」を用いることで、Unityアプリが10倍の速度向上
  • Chrome 70で、WebAseemblyがマルチスレッド対応

ビデオ用次世代コーデック「AV1」と画像フォーマット「WebP」

f:id:masahirotanaka:20181119132034p:plain:w400

Webサイトの容量の大半は、画像・フォント・JavaScriptが占めます。これらのファイルサイズをどう削減するかが、Webサイトの高速化にとって重要だということです。

たとえば、アニメーションGIFは非常に効率が悪く、お薦めできません。そのアニメーションGIFを動画(mp4形式)に変換するだけで、たとえば6.8MBあったものは420KBまで圧縮できます。また、動画の圧縮フォーマットとして、AV1コーデックを用いると、x264と比較しても40〜50%の圧縮を実現されます。(ただしAV1は現状Chromeでのみサポート

同様に、画像フォーマットとしてWebPを用いると、30%ほどのファイルサイズ削減となります(WebPはEdge / Chrome / Firefoxで利用可能)。この場合、非対応ブラウザーと組み合わせるために、下記のように<picture>タグを利用します。旧ブラウザにおいては、<img>タグの内容が解釈される仕組みです。

<picture>
    <source type="image/webp" src="image.webp">
    <img src="image.jpg">
</picture>

Webフォントも読み込み時間が長くなる要因の一つです。その対策として、font-displayというCSSプロパティが登場しました。font-display: swapと指定した場合、カスタムフォントを読み込まれるまでは、システムのフォントが代わりに表示されるようになります。

@font-face {
  /* ... */
  font-display: swap;
}

font-displayプロパティは、現状Firefox/Chrome/Safariで対応されています

Houdini

f:id:masahirotanaka:20181119132402g:plain:w300動画より

CSSの機能をJavaScriptで拡張できるようにするための仕組みです。Worklet、CSS Paint API、Layout API、Typed OMといった複数の機能から構成されています。

たとえばCSS Paint APIを用いると、これまでCSSでは表現できなかった描画(たとえば角丸以外のボーダーを持つオブジェクト)を、JavaScriptで描画することができます。

Houdiniの実装状況は、こちらのWebサイトから確認できます。Chromeだけでなく、SafariFirefoxでも開発が進んでいるようです。

Native Lazy Loading

画像などのリソースを読み込む時間を遅延するかどうかを、lazyload属性を用いてブラウザーに指示することができるようになります。画像とIFRAMEに対して適用できます。

たとえば、

<img src="image.jpg" lazyload="on">

とすると、ブラウザーは実際にそのコンテンツを表示する必要があるまで、画像ロードは行われません。デフォルトは「auto」、よってブラウザーが遅延読み込みを行うかどうかを判断します。要するに、この機能が組み込まれたブラウザーの場合、何もしなくても勝手に遅延読み込みが有効になるようです。

f:id:masahirotanaka:20181119133217g:plain動画より

Preloading

プリロードを用いると、画像やスクリプトなどのリソースを前もってロードすることができます。これにより、例えば次以降のページで必要なアセットを前もって取得しておき、ページ表示速度を高速化することが簡単に実現します。

プリロードを設定するには、<link>タグを使用します。新しく追加された rel="preload"属性を使用して、下記の通り記述します。

<link rel="preload" href="image.png" as="image">
<link rel="preload" href="script.js" as="script">

この機能はChrome/Safari/Edge(一部サポート)で利用できます。Service Workerを用いなくても、コンテンツのプリフェッチが簡単に実現できますね。

Web Packaging APIとPortals

AMP(Acceledated Mobile Pages)の仕組みにより、たとえばGoogleの検索結果から次のページへの遷移速度を向上させることができるようになりました。しかし、この仕組みはGoogleドメイン上で遷移先のページを表示する必要があるため、URLが二重に表示されたり、セキュリティ上の懸念につながってしまいます。

Web Packagingという仕組みを用いると、Webサイトの正当性を担保することで、ブラウザーがコンテンツをプリフェッチし、キャッシュさせることが可能になります。実際にCloudflare社のデモでは、AMP Packagerという仕組みが「Cloudflare Worker(V8の単位でエッジサーバーで動作させる技術)」を用いてWebパッケージが作成されていました。

もう一つの仕組みとして、IFRAMEに似た「Portal」という仕組みが紹介されました。これは、<portal>というタグを用いて実現されるもので、IFRAMEと同様にページ内に別サイトを組み込める仕組みです。IFRAMEとは異なり、そのコンテンツに遷移する際に、モーフィングアニメーションが表示されます。これにより、ネイティブアプリのような画面トランジションをWebサイト間で表現できます。具体的なデモでは、「となりのヤングジャンプ」と「はてな」による漫画ビューアーが紹介されていました。

f:id:masahirotanaka:20181119135245g:plain:w200Portalを用いた例

高速化の改善事例

上に挙げたような施策を、実際にWebサイトに対して適用した事例が、いくつも紹介されました。ここでは、PinterestSpotifyStarbucksといったメジャーなWebサイトの改善事例、そしてSquooshというGoogleがデモンストレーション目的で開発したツールについて、その内容を紹介します。

Pinterest

モバイルWebを一から作り直した(その作業は3ヶ月しかかからなかったそうです)。その結果、起動速度が4倍高速化(以前21.2秒だったのが5.6秒に)したとのこと。さらにServiceWorkerを用いたプリフェッチを行い、これまで23秒かったところが3.9秒まで削減。

より具体的な数字として、JavaScriptのサイズは、650kbから200kbまで削減できたそうです。その削減の取り組みにおいては、Performance Budgetの可視化が重要。具体的には、継続的インテグレーションを用いてPerformance Budgetを自動的に測定する仕組みを導入し、開発プロセスに組み込まれています。

  • ログ: WebPackのバンドルサイズを記録
  • 警告: コア機能のバンドルが大きくなったら開発チームに警告
  • 防止: ESLintを用いて、インポートに制約をつける

こうした努力を経て、ユーザーの体験は向上し、新規ユーザーのサインアップはモバイルWeb経由がNo. 1になったそうです。

Spotify

1年前(2017年)のSpotifyにはモバイルWeb版がなく、音楽を聞くにはネイティブアプリのダウンロードが必要な状態でした。しかし、ブラジルなどの新興国では、モバイル端末のスペックが低く、端末の容量が限られているため、アプリダウンロードのハードルが高い。1曲聞きたいだけなのに、何MBもするアプリをダウンロードしたくない、という反応が多かったそうで、A/Bテストを実施しながら、ユーザーの反応を見ていきました。

最初の実験として、アプリのダウンロードを行う前に、1曲だけWeb経由で聴ける仕組みを導入しています。そうすると、初日再生率は25%向上されました。そこで、次の実験として、モバイルWebプレイヤーを組み込んだWebサイトとそうでないWebサイトの2種類に分離し、ユーザーの反応を確かめました。すると、モバイルWebプレイヤーを組み込んだ場合、初日再生率は54%向上したそうです。

SpotifyのモバイルWeb対応には、Media Session APIやPWA対応が行われておりますが、ブラウザーにコンテンツ保護機能が加わったことも重要だったということでした。

Starbucks

2017年にPWA版をリリースしています。WorkboxやIndexedDBを用いた高速化で、従来よりも2倍の速度を実現されました。また、Credentials Management APIを用いてログインの仕組みをスムーズになっています。

アプリはReactベースで作られています。また、デスクトップ用WebサイトもPWA対応されており、実際にWebオーダーの25%はデスクトップから行われてるようになりました。

Squoosh

Chrome ChromeのDeveloper Advocateチームが中心になって、PWAやWeb Assembly、WebWorkersなどをフルに活用して開発した画像圧縮サイトです。GitHubで公開されており、Chromeだけでなく、Edge/Safari/Firefoxでも動作します。

圧縮コーデックであるC/C++のライブラリはEmscriptenを用いてWebAssemblyに変換されています。そして、CPUコストの高い圧縮機能は、WebWorkersを用いてUIスレッドと分離し、画像圧縮中でもスムーズな描画ができるよう配慮されています。Webサイトは完全なPWA実装となっており、モバイルやタブレットでも動作します。

最後に

昨年までは「PWA」をいかに浸透させるかがテーマの中心だったように思いますが、今回のChrome Dev Summit 2018では、PWA(そしてPWAの真髄であるネイティブ並みのパフォーマンス体験)を具体的に実現するためのノウハウやテクノロジーが余すことなく紹介されたように思います。

ブラウザーに対する機能強化が、ペースダウンすることなく進んでいることが印象に残りました。一方で、たとえばHoudiniがEvergreen化された場合にCSS3・SVGWebGLCanvasとの棲み分けはどうしたらいいのか、より巨大化するブラウザーのランタイムは全体性能を低下させているのではないか、などの疑問も生まれそうです。

Chrome Dev Summit 2018、まとめると凄く楽しかったです!