Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AbemaTVはただのSSR じゃねぇんだよ

AbemaTVはただのSSR じゃねぇんだよ

2018/07/06 Frontrend Vol.12 - サービスの誕生と成長

発表者:
- SSRについて @kubosho
- CDNについて @ktknest

https://frontrend.connpass.com/event/90107/

Kenichi Kato

July 06, 2018
Tweet

More Decks by Kenichi Kato

Other Decks in Programming

Transcript

  1. AbemaTVはただのSSR
    じゃねぇんだよ
    @kubosho @ktknest
    2018/07/06 Frontrend Vol.12 - サービスの誕生と成長

    View Slide

  2. ここ数年のWebアプリケーションにおけるSSRとは
    ● SSR = Special Super Rare Server Side Rendering
    ● サーバー側で初期表示に必要なHTMLツリーを作って返すこと
    ● 狭義では、Reactの renderToString() で作ったHTML文字列を、Expressの
    res.send() で返すこと

    View Slide

  3. ただのSSRじゃねぇ?
    どういうことだ? 

    View Slide

  4. ありそうな話
    ● 新規にWebサービスを立ち上げて、そこでSSR + SPA構成にしました!
    ● SPAをやめてSSRだけにしました!
    ● SPAをしているWebサービスの構成を変えるついでに
    SSRもするようにしました!

    View Slide

  5. AbemaTVの場合
    ● 新規に何かサービスを作ったわけではない
    ● SSRに加え、従来と同様のSPAも継続している
    ● 既存のコード設計やデータフロー、使うライブラリなどはあまり変えずに
    SSRした

    View Slide

  6. SSR実装について

    View Slide

  7. なぜAbemaTVではSSRをするようにしたか
    ● SSRをすることにより、ユーザーにとって意味のあるコンテンツが速く表示されるよ
    うにしたかった
    ● ページ全体をSSRすることにより、ページをよりマシンリーダブルにする
    ○ スプラッシュ画面はSSRをしていたがページの情報量が不足している
    ○ 検索エンジンのクローラーに、より情報を読み込ませる目的があった

    View Slide

  8. ページ全体をSSRするようにした効果
    ● サービス名や番組名で検索したとき *.abema.tv から始まるページが
    上位に出やすくなった
    ○ SSRをしているページ(※1)でユーザーにとって意味があるコンテンツがより速
    く表示されるようになった(※2)ことが関係している?
    ■ ※1 トップ・エピソード一覧・エピソード詳細ページが対象
    ■ ※2 指標で言えばSpeed IndexやFirst Meaningful Paint Timeなど
    ○ ページの内容が初期表示時に読み込まれるようになって、検索エンジンのク
    ローラーに認識されやすくなった?

    View Slide

  9. デモ

    View Slide

  10. SSR実装でハマったところ

    View Slide

  11. 開発時にバックエンド側でエラーが多発した
    ● 元々SSRすることを想定して作られていなかった
    ○ ブラウザ上でしか動かないコードが多かった
    ○ window や localStorage などのプロパティを触っている箇所でエラーが出

    ● モジュールをインポートする際に余計なものが読み込まれていた
    ○ 必要なものだけを読み込むようにした

    View Slide

  12. バックエンドとクライアントで描画の差異があった
    ● バックエンド側でタイトルや説明文などのメタデータしか返してなかった
    ○ コンポーネントを描画するためのデータが足 りてなかった
    ● 結果 Warning: Expected server HTML to contain a matching
    in が多発した
    ○ console.log() やHTMLのソースを見て、コンポーネント描画に必要なデータ
    を返すようにした
    ○ SSRできないものは componentDidMount() が実行された後に描画するよう
    にした

    View Slide

  13. まとめ

    View Slide

  14. まとめ
    ● SSRをするようにしたらページの表示速度が速くなって良かった
    ○ 速くなったことによりユーザー体験が上がったと思う
    ○ SEOという意味でも効果があった
    ● SPA + SSR構成をやる場合は、最初からやったほうが途中で導入するより楽
    ○ 最初からブラウザとバックエンド両方で動くように考慮できそう
    ● 課題もまだあるけど引き続き潰していきたい
    ○ ページの表示高速化はまだやれるところがある

    View Slide

  15. CDN導入について

    View Slide

  16. 以前のAbemaTVとCDN
    Cloud LB
    Cloud CDN Kubernetes
    Engine
    Nginx
    Node.js
    https://abema.tv

    View Slide

  17. SSR化にあたっての課題
    ● デスクトップとモバイルで異なるHTMLやJS/CSSを配信したい
    ○ Cloud CDNではVary: User-Agentによる条件分岐はできない
    ○ SSR化するには、これが可能な CDNへの移行が必要になった
    デスクトップ モバイル
    全く異なる

    View Slide

  18. Cloud LB Kubernetes
    Engine
    Nginx
    for Fastly
    Node.js
    https://abema.tv
    現在のAbemaTVとCDN
    Fastly

    View Slide

  19. Fastlyを選んだ理由
    ● 次世代CDNの豊富な機能
    ○ インスタントパージでキャッシュ即削除
    ○ Varnishベースのため、VCLで柔軟なカスタマイズができる
    ○ HTTP/2 Server Push が使える
    ● 社内での先行事例あり (https://www.superchoice.bet/)
    ○ 各種設定を始め、VCLカスタムやノウハウを参考にできそう
    ● 一度は使ってみたかった(チーム一同)
    ○ とても大事!

    View Slide

  20. Fastly移行の課題

    View Slide

  21. TLS 1.0/1.1 が利用できなくなる
    ● AbemaTVの推奨環境で影響がないか確認
    ● Desktop / iOS 9+ / Android 5+ OK
    ● Android 4.4
    ○ 標準ブラウザ NG → サポート外とする
    ○ WebView(Chromium 30) OK
    FYI: [Android4系端末のTLS1.1&1.2対応について](https://qiita.com/ntsk/items/9f31fc7b44c04ea45e0b)

    View Slide

  22. UA別のキャッシュ振り分け
    ● Varnish: 設定方法
    ● Varnish: UAやファイル種類に応じて識別ヘッダーをセット
    ● Varnish: 識別ヘッダーをVaryヘッダーにセット
    ● Node.js: 識別ヘッダーを使って内部の分岐に利用

    View Slide

  23. Varnish: 設定方法
    ● FastlyではVCLを直接記述する方法が以下用意されている
    ○ カスタムVCL: 独自のVCLファイルを作成することができる
    ○ VCLスニペット: カスタムVCLを使わずに、小さなVCLロジックを挿入できる
    ● AbemaTVではカスタムVCLを利用
    ○ 要件上は、VCLスニペットでも表現可能
    ○ Fastlyの全設定をTerraformを通して反映しており、 TerraformがVCLスニペット未対応
    ○ 今後の拡張性も考慮
    UA別のキャッシュ振り分け

    View Slide

  24. Varnish: UAやファイル種類に応じて識別ヘッダーをセット
    公式のガイドをほぼそのまま使用 https://docs.fastly.com/guides/vcl/delivering-different-content-to-different-devices
    ● X-UA-Device: desktop, tablet, smartphone, native, na
    ● X-UA-Vendor: generic, apple, android, etc...
    画像リソースなどは
    UA別にする必要がないので一律 X-UA-Device: na とする
    UA別のキャッシュ振り分け

    View Slide

  25. Varnish: 識別ヘッダーをVaryヘッダーにセット
    UA別のキャッシュ振り分け
    Vary: …, X-UA-Device, X-UA-Vendor として、別々にキャッシュさせる

    View Slide

  26. Node.js: 識別ヘッダーを使って内部の分岐に利用
    UA別のキャッシュ振り分け
    - X-UA-Device, X-UA-Vendror が共にある場合
    - デスクトップ or モバイルや、iOS or Android の判定に利用する
    - SSR結果を変え、Varyヘッダーによりキャッシュもそれぞれで行われる
    - X-UA-Device, X-UA-Vendror のどちらかがない場合
    - リクエスト情報のUserAgentを見て判定を行う(従来通り)
    - 移行直前や切り戻しで、 Fastlyを経由しないケースにも対応するため

    View Slide

  27. オリジンシールドによるヒット率の向上(未遂)
    ● オリジンサーバーへのアクセスをシールドPOP経由にする仕組み
    ○ エッジPOPからのリクエストはシールド POP経由になる
    ● 但し、国内限定では目立った効果がないとのこと
    ○ Fastly社からの設定レビューでアドバイスをもらう
    ○ エッジサーバーが少ない故(日本では数箇所)
    ○ 結果、無効にした
    https://docs.fastly.com/ja/guides/performance-tuning/shielding.html

    View Slide

  28. オリジンサーバーの要件
    ● 従来のURL https://abema.tv とは別のURLで提供する
    ○ https://abema.tv はFastly用になるため
    ● 通常のアクセスはできないようにする
    ○ 認証用のリクエストヘッダーを定義
    ○ FastlyのVarnish設定で、オリジンサーバーへのリクエスト時に追加する
    ○ オリジンサーバー側でチェックし、無効な場合は 401を返す
    ● Cloud CDNを無効にする
    ○ 二重CDNにならないように

    View Slide

  29. 稼働状態からの移行方法
    ● Cloud LBで従来のURLとオリジンサーバー用のURLを設定
    ○ ① 従来のURL: Cloud CDNを有効 - Nginx
    ○ ② オリジンサーバー用の URL: Cloud CDNを無効 - Nginx for Fastly
    ● https://abema.tv のDNS設定で、切り替え・切り戻しを行う
    ○ GCP宛: ①で受け、Cloud CDN経由で配信する
    ○ Fastly宛: Fastlyで受け、②からリソースを取得し、 Fastly経由で配信する

    View Slide

  30. 現在のAbemaTVとCDN(詳細版 - Cloud CDN)
    Cloud LB
    Cloud CDN
    Kubernetes
    Engine
    Nginx
    Node.js
    Nginx
    for Fastly
    Fastly
    https://abema.tv

    View Slide

  31. 現在のAbemaTVとCDN(詳細版 - Fastly)
    Cloud LB
    Cloud CDN
    Kubernetes
    Engine
    Nginx
    Node.js
    https://abema.tv
    Nginx
    for Fastly
    Fastly
    認証用のリクエストヘッダーを付与

    View Slide

  32. \ 無事に移行完了 /

    View Slide

  33. 結果
    ● キャッシュヒット率がAvg 90%以上
    ○ 思ったよりも高い数値だった
    ● 1週間ほどの検証期間も問題なく経過
    ○ その後、SSRを有効化

    View Slide

  34. 今後の予定
    ● より細かい分類によるキャッシュの最適化
    ○ 課金プランごとに一部表記が異なる等
    ■ 現在のSSRはどちらにも対応できる形にし、 Clientで再描画を行っている
    ● ブラウザ毎の配信JSの最適化
    ○ サポート状況に合わせたファイルを配信する
    ● 切り戻し手段の再考
    ○ 現時点では、以前の構成にすぐ戻せる形にしている
    ○ 普段使わないファイル群が残ったままになる
    ■ メンテが煩雑化、いざ戻した際も動作が保証しきれない

    View Slide

  35. ご清聴ありがとうございました ☕

    View Slide