c0d3man52

Webサイト制作

【2020年版】個人的にベストなフロントエンドJAMstack構成

2020年版現在の、個人的にベストなフロントエンドJAMstack構成(Vue.js + HUGO)とサーバーについてまとめてみました。

公開日: 2020.3.25

JAMstackサイトの構成

開発コスト、ユーザーメリット、サーバーコスト、どれをとっても個人的には今後は「JAMstackだな」と感じていて、より低コストで高速なWebサイトを構築する方法を模索していました。

ここ1年くらい試行錯誤して「Vue.js + HUGO」という構成に落ち着きました。

Vue.js (Javascript)

Vue.jsは基本的にはドキュメントルートから読み込んだ時のみ発火する設定にしています。

というのも、後述するSSRやAMPに対応しようとすると、どうしてもAMP用の静的ファイルが必要で、そうするとAMPページでは「router-link」が発火できないためです。

ただし、PWA化することで、Service Workerが先んじてAMPページからVueアプリ側をプレキャッシュしてくれるので、Vue.jsファイルの重さを軽減させることができます。

HUGO (HTML/AMP/json)

コンテンツの中身(データ)は、AMPページ + コンテンツjsonファイル(APIがわり)の配信元として、静的ファイルジェネレータのHUGOを使っています。

流れ的には、

  • HUGOでHTMLページ(フルAMP)、ページデータのjsonを出力
  • 検索エンジンにはHTML(AMP)ページをインデックス
  • Vue.js側からはjsonファイルをロードしてSPAとして動作

とすることで、HUGOが吐き出すHTMLをSSRとして利用&AMPにも対応しつつ、jsonファイルも出力することで、HUGO自体をAPIサーバーにしてAPIサーバーコストも削減しています。

SPAだと、SNSなどでリンクを貼られた時にogpヘッダをロードしてくれない問題がありますが、この方法ならそこも回避できます。

データ構造的には下記のようなイメージです。

- index.html // Vue.js
- /topics/hoge/index.html // HTML(AMP) -> ここを検索エンジンにインデックス
- /topics/hoge/index.json // データのjson

CI/CDでビルドする際は、

  • HUGOで静的サイトをビルド(HUGOの/index.htmlも吐き出すけど、yarn buildで上書き)
  • yarn buildでVue.jsをビルド

という感じにしています。

SSR & API

HUGOで吐き出すHTMLは、基本的にフルAMPで生成しています。

こうすることで、AMP用のURLを別途用意する必要もなく、SSRも必要がないため、ビルドもスピーディになります。

また、JAMstackと言えばコンテンツをAPIから出すというイメージですが、Vue.jsでデータを受け取るためのデータ(json)は、基本的にHUGOで生成して同一ドメインから配信しています。

HUGOはコンテンツだけでなくデータも扱えるので、データベース的にも使えます。

データをAPI的に使うためには、

  • データベースからdataテンプレートにjsonファイルを出力する
  • APIサーバーを用意して、HUGOで取り込む

という2パータンを使用しています。

検索などリアルタイムで使いたいAPIがある時はAPIサーバーから、記事などの静的コンテンツのみを使う場合はすべてHUGOから吐き出しています。

サーバー

配信サーバー

サーバーは、NetlifyとGitlab pagesを使い分けています。

どちらもHUGOをビルドできるのですが、両者で使い分けるポイントは、

  • Netlifyはrewrite/redirectができる
  • Gitlab pagesはビルドタイムが多い(2000分 vs 300分)
  • Gitlabはdocker imageが使える

という点です。

ビルド時間が多いので基本的には、Gitlab pagesを使って、rewriteなど高度な設定が必要な場合はNetlifyという形で使い分けています。

動的APIが必要な際は、Node.jsのexpressでGraphQL APIとしてnow.shから配信しています。

CDN

CDNは定番のCloudflareで、静的ファイルは基本的にキャッシュさせています。

CloudflareはPage ruleを設定すれば、jsonファイルもキャッシュしてくれるので、データによってはHUGOが吐き出すjsonファイルもキャッシュさせて、Netlifyへのデータ転送量を削減させています。

データ転送量という意味では、Webサイト自体が、

  • 検索経由はAMPなのであまり転送がない
  • PWAなのでアプリ本体はprecacheでローカル保存させている

という構造なので、そもそも転送量は少ないのですが、そこからさらにCloudflareで削減する感じです。