一休.com

フロントエンド

パフォーマンス最適化

Ryo Utsunomiya(@ryo511)

Bonfire Frontend #3

2019-01-24

自己紹介

  • 宇都宮 諒(うつのみや りょう)​
  • 株式会社 一休 宿泊事業本部 エンジニア
  • UIチーム所属
  • 主な仕事

Agenda

  • 一休.comと一休コンシェルジュ
  • パフォーマンスの計測
  • パフォーマンスの最適化戦略
  • パフォーマンスのためのアーキテクチャ

一休.com

  • https://www.ikyu.com
  • 高級ホテル・旅館の宿泊予約サービス
  • ユーザ単位でコンテンツの出し分けが必要
  • 広告無し
  • 10年物のサイトなので、作りが古いところが多数あり
  • ページスピードを考慮しない作りになっているところも多数あり

一休コンシェルジュ

  • https://www.ikyu.com/concierge/
  • 高級ホテル・旅館を紹介するオウンドメディア
  • ユーザ単位でコンテンツの出し分けは不要
  • 広告無し
  • WordPress製
    • WordPressをはじめ、CMSはデフォルトだと遅いことが多い

「最適なパフォーマンス」とは?

  • Webサイトの種類や性質によって、最適化のポイントは異なる
  • ECサイトやメディアサイトはロード時間が重要
  • 一方、ゲームなら、ロードは多少長くてもよいが、プレイ中に動作が重くなるのはNG
  • 本セッションでは、ECサイト・メディアサイトのパフォーマンス最適化について扱います

最適化のものさし

  • 最適化の度合いを測るためには、ものさしを用意する必要がある
  • 現在、Webフロントエンドにおけるパフォーマンス計測のデファクトスタンダードはLighthouse
  • Chrome DevToolsをはじめ、PageSpeed Insights、WebPageTestなど、さまざまな計測ツールがLighthouseベースになっている
  • 計測環境を一定化するという意味で、ローカルのChrome DevToolsより、PageSpeed InsightsやWebPageTestのほうがオススメ

PageSpeed Insights

  • Webページのスピードを計測できるサービス
  • Lighthouseのスコアや診断を確認できる
  • 初心者でも使いやすい

WebPageTest

  • 計測環境や条件を設定可能
  • やや上級者向け

LighthouseのスコアとScale

  • Lighthouse v3 Scoring Guideでは、100点満点のスコアによって、サイトの速さを以下の3つに分類している
    • 0〜49: Slow
    • 50〜89: Average
    • 90〜100: Fast

Lighthouseスコアの内訳

  • Lighthouseはページのロードに関する5つの指標に重み付けをして、スコアを計算している
    • First Contentful Paint(3)
    • First Meaningful Paint(1)
    • SpeedIndex(4)
    • First CPU Idle(2)
    • Time To Interactive(5)
  • 100点満点を取るには、First (Contentful|Meaningful) Paintが1.3秒、それ以外が1.9秒以内に完了する必要がある

スコアを見るか指標を見るか

  • スコアは様々な指標を計算した結果
    • 計算式はLighthouseのバージョンアップによって変わることがある
  • 絶対評価のものさしとして使うべきではない
    • Calibre等を使ってるなら、Lighthouseスコアではなく、TTIやSpeedIndexをウォッチすべき
  • 相対評価のものさしとしては便利
    • 他のサイトと比較して、どの程度の位置づけにいるかがすぐにわかる

PageSpeed Insightsの計測環境

  • PageSpeed InsightsはSimulated 3Gのプロファイルで計測している
  • Simulated 3Gの回線速度は下り1.4Mbps
    • 読み込んでいるリソースの量が多いとスコアが悪化しやすい
  • まっさらな状態で計測するので、Service Workerによる高速化は効かない
  • モバイルは厳しめ、パソコンは甘めの結果が出る印象

スコアごとの代表的なページ

  • 90〜100
    • example.com、dev.to、googleトップ等
  • 70〜89
    • メルカリトップ、日経電子版記事ページ等
  • 50〜69
    • Yahooトップ、ヨドバシ.com等
  • 30〜49
    • 多くのサイトはこのスコア帯
  • 0〜29
    • 遅いサイトはこのスコア帯

サイト種別と最適化ターゲット

  • ECサイト
    • 50を超えれば、大半のECサイトより速くなる
    • 70以上なら業界トップクラス
  • メディアサイト
    • 70超えがマイルストーン
    • サイトの要件(広告やパーソナライズの有無)次第では90超えも狙える

一休.comのスコア

  • トップページ: 32
  • ホテルリストページ: 41
  • ホテルページ: 72
  • ホテルページ(AMP): 80
  • ホテルページのみ突出して良いのは、パフォーマンス最適化の成果

ホテルページの各指標

  • 表示は速いが、ロード完了は遅い
  • => TTIの削減をターゲットにすることで、パフォーマンス改善が見込めそう
  • => TTIが遅くなっている原因は?
  • => サードパーティスクリプト
  • => サードパーティスクリプトを最適化すれば、さらに改善できそう

一休コンシェルジュのスコア

  • トップページ: 79
  • 記事ページ: 84
  • 改善できる項目はまだまだある。が、現状でもかなり速い

Webサイトの一般的な最適化戦略

  • 「遅い」要素を減らすことで、速くする
  • 「遅い」要素とは
    • サイズの大きな画像/フォント
    • JavaScript
    • 大量のHTTPリクエスト
    • 重いDBアクセス
    • etc...
  • ただし、サイトの性質によって、利用できる最適化のオプションは異なる

一休.comの特徴

  • データのリアルタイム性が重要
    • 価格・在庫はリアルタイムに反映する必要がある
    • => データを長期間キャッシュできない
  • 細かい検索クエリに対応する必要があるため、キャッシュ効率も低い
  • ホテル詳細ページはコンテンツが多くなりがち

一休.comの最適化戦略

  • 画像のサイズを適正に抑える
    • Imgixを利用して画像を最適化
  • Above the Foldに入らない画像はlazyloadする
  • レンダリングブロック解消(済み)
  • JavaScriptのサイズをできるだけ減らす
    • ​ただし、使いやすさを向上させるためにJSを使うのはあり

一休コンシェルジュの特徴

  • ユーザに見せるコンテンツは、原則として同じ
  • 一度公開したコンテンツは、あまり更新されない
  • 会員限定コンテンツなし
  • 広告なし
  • => 最適化が非常にしやすい!

一休コンシェルジュの最適化戦略

  • Fastlyのキャッシュを活用することでTTFB最小化(10〜20ms)
  • 画像の最適化(Imgix)
    • 記事の中で使われている画像もちゃんと最適化されるように
  • JSはできるだけ使わない
  • AMPの活用
    • WordPressのAMPプラグインで、Canonical AMP化を検討中

パフォーマンスのためのアーキテクチャ

  • フロントエンドのアーキテクチャ選択は、パフォーマンスに大きな影響を及ぼす
    • SPAかMPAか
    • SSRするか
    • フレームワーク・ライブラリ選定
    • CDNのキャッシュ戦略
    • Service Workerの活用
  • フロントエンドのアーキテクチャパターン
  • JavaScript, APIs and Markup の頭文字を取ったもの
  • 静的なHTMLをベースに、動的な部分はJSとWeb APIで構築する
    • CDNによるキャッシュが効くので、TTFBを最適化できる
  • サーバサイドはAPIのみ(重要)
    • JAM StackにSSRはない
  • メリットは、パフォーマンスと、疎結合

JAM Stack風アーキテクチャ

  • (Railsのような)普通のWebアプリケーションでは、静的HTMLのみという構成にはしづらい
  • しかし、共通部分(App Shell)をCDNでキャッシュすることは可能
  • これによって、JAM Stackと同等のパフォーマンスを普通のWebアプリケーションでも得られる

JAM StackとSEO

  • JAM StackはJSのクライアントサイドレンダリングを活用する
  • GooglebotはChrome 41相当のJSを実行できる
    • が、インデックス反映は最大で1週間遅れる
    • リアルタイム性の重要なサイトで、1週間遅れは痛い
  • クライアントサイドレンダリングをしつつ、SEOする方法はないか?

Dynamic Rendering

  • Googlebotに対して、JS描画済みの静的HTMLを返却する
  • 手法としては昔からあるが、最近Googleのお墨付きになったのが大きい
  • 一休ではRendertronによるDynamic Renderingを実験中
    • 部分展開をして、少しずつ適用範囲を広げている

Next Ikyu Frontend

  • Fast 3GでTTI 5秒以内をターゲットに
  • JAM Stack風アーキテクチャでTTFB改善
  • トップ+リスト+詳細のSPA化を検討中
    • 各ページが十分に速ければ、SPAにしなくてもよいかも?
  • SSRは優先度低め
    • SEOはDynamic Renderingによって担保する
    • もう一段先の速さを目指すなら必要
  • Service Workerの活用
  • サードパーティスクリプトの最適化

まとめ

  • パフォーマンス最適化は適切な計測から始まる
  • パフォーマンスの伸びしろは、サイトの要件次第
  • 大幅なパフォーマンス改善にはアーキテクチャレベルの変更が必要