🐕

AWSのSPAアプリケーションにおけるダイナミックレンダリングの実装(アーキテクチャ編)

2020/09/17に公開

SPAでサービスを作ったのですが、SEO関連で課題があり、ダイナミックレンダリングの対応を取った話です。

インフラは全てAWSで固めたので、AWSを利用していない場合、参考にならないかも知れません。

また、サンプルのソースコードはGitHubにあります。
https://github.com/snicmakino/dynamic-rendering-lambda

※ これは現時点で有効な話なので、今後の動向次第では有効な対応ではなくなるかも知れません。

効果

良い点

  • 検索エンジンに、全てのページがレンダリング後の状態でインデックスされる
  • TwitterやSlackでの共有時に、個別ページのOGPが展開されるようになる
  • 実装が(SSRと比較すると)楽で、フロントエンドのフレームワークに関係なく利用できる

イマイチな点

  • レンダリングに少し時間がかかる(5秒くらい)

所感としては、SSRを利用するほどコストかけられないが、SEO対策はある程度やりたいといったケースに適しています。

レスポンスタイムがSEOで滅茶苦茶不利になっているような感覚も無いので、十分SSRに対抗する選択肢になり得るかと思います。

ダイナミックレンダリングについて

ダイナミックレンダリングとは

Googleさんのガイドを参考にするとわかりやすいです。

SPAでは通常、ブラウザに真っ白なHTMLが最初に返却され、JSが動いて描写されるという動きをします。

特にSEOを意識しない場合は問題ないのですが、検索エンジンのBotなどは、このJSを動かした後の画面を読み込んでくれないことも多く(Googleは結構頑張ってますけど)、コンテンツページなどもデフォルトで設定してあるタイトルを読んでしまったりします。

これではまずいので、ボットに返却するhtmlは、JSを動かして、ちゃんとコンテンツがある状態にしてしまおう(レンダリングする)というのがダイナミックレンダリングです。

サーバサイドレンダリング(SSR)との違い

SSRは、全てのアクセスに対して、レンダリングを行います。
対してダイナミックレンダリングでは、bot等の一部のアクセスに対してのみレンダリングをするという違いがあります。

検索エンジン向けのコンテンツと中身を分けるという事なので、あまりSEOに良く無さそうと心配されるかもしれませんが、Googleさんも推奨している方法なので、安心して使って良いかと思います。

インフラ構成

インフラはAWSで固めており、CloudFront、S3、Lambda@Edgeを利用した構成です。
それぞれのサービスを軽く説明します

S3

みんな大好きS3、SPAのhtmlやjs等のリソースの置き場所です。
静的ウェブサイトのホスティング機能を利用します。

CloudFront

みんな大好きCDN、AWSサービスとの親和性は当たり前ですが素晴らしいです。
ハンドリングの設定をもうちょっと柔軟にしたいですお願いします

Lambda@Edge

CloudFrontでのアクセス時に、なんとAWS Lambdaを動かすことが出来ます。
動かすタイミングは4種類設定でき、今回は以下の2つを使います。

  • Viewer Request
    CloudFrontがユーザーからリクエストを受信したときに動きます。
    Botかどうかを判断する処理を行います。
  • Origin Request
    CloudFrontからS3へのリクエスト時に動きます。
    Botだった場合のレンダリング処理を行います。

設計のポイント

Lambda@Edgeの使い方について疑問に思った方も多いかと思うので解説します。

Viewer RequestとOrigin Requestの2つを利用している理由

Viewer Requestだけで全部処理したほうが良いと感じるかも知れませんが、Lambda@Edgeの制限により、この構成を取っています。

ダイナミックレンダリングでは、Lambda上でブラウザを動作させて、レンダリングされたHTMLを返すのですが、ブラウザを動作させるには大きなメモリサイズと、そこそこの時間がかかります。

これがViewer Requestだとメモリ128MB、タイムアウト5秒と制限されてしまうため、動作させることが出来ませんでした。

そのため、重い処理の部分は屈強なLambdaを用意できるOrigin Requestにまかせています。

Lambda@Edgeの実装

次回、Lambda@Edgeの実装周りについて書きます。
とりあえずソースさえあれば十分という方はGitHubを参考にしてみてください。
https://github.com/snicmakino/dynamic-rendering-lambda
(未検証だけど多分動作するはず)

SPAをCloudFront上と連携して公開する方法は沢山情報あるので、ここでは説明を省きます。
Lambda@Edge周りに関して説明します

Discussion