Jamstack Advent Calendar 2019の4日目の記事です。
今回は、Jamstackという言葉が何を指すのかについて考察したいと思います。
なぜこの記事を書こうと思ったかというと、人によってJamstackという言葉の定義が異なっていると感じたためです。
Jamstackの公式サイトから読み解いていきたいと思います。
https://jamstack.org/
以下、和訳(イタリック)と考察(太字)です。
Jamstackとは何か
あなたはもうすでにJamstackなサイトが動いているのを目にしているかもしれません。
JavaScript, API, Markupの全てを含んでいる必要はありません。
自力でビルドされていても、JekyllやHugo、nuxt、Next、Gatsby等の静的サイトジェネレータで作られていても良いです。
すべてに共通するのはWebサーバーに依存しないという点です。
→Webサーバーに依存しない、つまりサーバーレスである
次にJAMの各頭文字の説明です。
JavaScript
req/resの動的プログラミングはすべてJavaScriptによって処理され、完全にクライアント上で実行されます。
これは、任意のフロントエンドフレームワーク、ライブラリ、またはバニラJavaScriptでもかまいません。
APIs
全てのサーバーサイドの処理やデータベースアクションは再利用可能なAPIとして抽象化されており、JavaScriptによるHTTPS経由でアクセスされます。
これらはカスタムビルドしても良いですし、サードパーティのものを使っても良いです。
→サーバーサイドの処理は再利用可能なAPIとして抽象化されている
Markup
マークアップのテンプレートはデプロイ時に事前ビルドされているべきです。
たいていはサイトジェネレータを使うか、ウェブアプリのビルドツールを使うかになるでしょう。
→事前ビルドされた静的なファイルからJavaScript経由でAPIを呼び出している
Jamstackとは呼べない例
- WordPressやDrupalといったサーバーサイドCMSによって構築されたサイト
- RubyやNodeといったサーバーサイド言語で作られたモノリシックなWebアプリ
- SPAの中でも初期ロード時にSSR(サーバーサイドレンダリング)をしているWebアプリ
→サーバーサイドでテンプレートを動的に構築してはいけない
なぜJamstackを使うのか
パフォーマンスが良い
デプロイ時点でテンプレートを生成できるのに、サイトにアクセスしたタイミングでテンプレートを構築する必要がありますか?
事前ビルドしたファイルをCDN経由で配信すれば、最初の送信時間を限りなく短くできます。
→事前ビルドしたファイルはCDNから配信
高いセキュリティ
サーバー側の処理がマイクロサービスAPIとして抽象化されているため、攻撃の対象領域を減らすことができる。
さらに専門的なサードパーティのサービスを活用することもできる。
安く、スケールしやすい
どこにでも配信可能なファイル群をデプロイする場合、スケーリングにおける問題点はこれらのファイルをどれだけ多くの場所で展開できるかということです。
それにはCDNが最適です。
開発体験の向上
フロントとバックの分離により、より開発とデバッグに集中することができます。
またサイトジェネレータのCMSオプションの選択肢が拡大するため、コンテンツとマーケティング用に個別のスタックを維持する必要がなくなります。
==========
一旦ここまでの話をまとめると、Jamstackとは下記の条件を満たすサイトとなります。
- Webサーバーに依存しないサーバーレスな構成である
- 事前にビルドされた静的なファイルからJavaScript経由でAPIをコールする
- 静的ファイルをCDNから配信している
これらの内容からまず連想できるのは、サーバーレスなSPA構成です。
index.htmlを起点にAPIは全てLambda等のcloud functionsで構成されているものです。
サーバーレスなので、スケールがしやすく、全ての通信がAPIを介するのでセキュリティも担保しやすいです。
おそらくこの構成自体は数年前からあったと思います。(弊社も2年前くらいからずっとこの構成です)
この構成に対して、Jamstackという名称がつけられたことで呼びやすくなったのではと考えています。
==========
次に、再び公式サイトに戻り、Jamstackのベストプラクティスの紹介を見てみます。
ベストプラクティス
プロジェクト全体をCDNに載せる
サーバーサイドのコードに依存しないため、単一のサーバーに頼ることなしにデプロイできます。
CDNから直接配信すると、他の追随を許さない速度とパフォーマンスを得られます。アプリをよりエッジなサーバから配信するほど、ユーザーエクスペリエンスが向上します。
全てはGit上で動く
Jamstackプロジェクトでは、だれでもgit cloneを実行し、必要な依存関係を一般的な手順(npm install等)でインストールし、完全なプロジェクトをローカルで実行する準備ができている必要があります。データベースのクローン、複雑なインストールは不要です。これによって開発者の摩擦を減らし、ステージング環境やテスト環境をよりシンプルにできるでしょう。
モダンなビルドツール
最新のビルドツールを活用してください。動きの速い領域ですが、未来のウェブ標準を今から使うことができます。それはBabel、PostCSS、Webpack等により可能です。
自動ビルド
Jamstackマークアップは事前に構築されているため、コンテンツの変更は別のビルドを実行するまで有効になりません。このプロセスを自動化すると、多くのフラストレーションを軽減できます。 Webhookを使用してこれを自分で行うか、または公開用のプラットフォームを使用できます。
→ここで初めてビルド時にコンテンツ内容を含んだマークアップを生成する的な文脈が登場します。
アトミックデプロイ
Jamstackプロジェクトが非常に大きくなると、新しい変更には数百のファイルの再デプロイが必要になる場合があります。これらを一度に1つずつアップロードすると、プロセスの完了中に一貫性のない状態になる可能性があります。これを回避するには、すべての変更されたファイルがアップロードされるまで変更が反映されない「アトミックデプロイ」を実行できるシステムを使用します。
→ここも同様です。
瞬時のキャッシュ無効化
ビルドからデプロイまでのサイクルが定期的に発生する場合、デプロイがいつ反映されたのか知る必要があります。 CDNがキャッシュの無効化処理をできるようにすることで、疑念を解消します。
再び考察
ベストプラクティスの章で、どうやら単なるサーバーレスのSPAではなさそうな描写が見えてきました。
実は最近、Jamstackというと下記のような構成を指すことが多いです。
ヘッドレスCMSにコンテンツを入稿すると、Webhook通知によりCIが回り、アプリケーションのビルドが始まります。
このビルドの際に静的サイトジェネレータがAPIをコールし、コンテンツを事前に埋め込んだ静的ファイルが生成されます。
静的ファイルはそのままホスティングサーバーにデプロイされ、CDN経由でユーザーに配信されます。
この方式は、JamstackのMの部分をより効率的に活用しています。
メディアなどの静的コンテンツの場合、基本的にユーザーログインはなく、コンテンツは全員に対して届けられます。
よって、記事などのコンテンツをユーザーのアクセス時に動的に生成する必要がなく、事前ビルドによりコンテンツをあらかじめテンプレートに含ませることができます。
この形式はJamstackとして最もパフォーマンスを上げやすい形だと言えます。
逆にユーザーのログインが必要なWebアプリケーションではこの手法はあまり向きません。
ユーザーごとに表示する内容が異なるのに、事前にテンプレートを構築しておくことはできないからです。
もしやるとするならば、動的なWebアプリケーション内でも全ユーザーに共通な部分(全体へのお知らせ等?)のみ、事前に静的テンプレート化しておく感じかなと思います。
SSG + CSR
SSG(スタティックサイトジェネレート)とは、静的サイト生成を指します。
それに加え、CSR(クライアントサイドレンダリング)を合わせた形がJamstackとしては最もパフォーマンスを発揮できる構成でしょう。
(CSRはJamstackの概念として必須ではないです。おそらく。)
数年前まで、初期ロード時はSSR(サーバーサイドレンダリング)で、その後のページ遷移はCSRを行うというのが、シングルページアプリケーションの恩恵を受けつつもSEOの対策もできる形として長らく注目されていました。
Jamstackは初期ロードがSSGされた静的ファイルとなるため、よりパフォーマンスを高めた形になっています。
Next.js / Nuxt.js / Gatsby あたりは簡単にこの構成を作ることができるのでオススメです。
まとめ
おさらいです。
Jamstackとは次のような特徴を持つサイトでした。
- Webサーバーに依存しないサーバーレスな構成である
- 事前にビルドされた静的なファイルからJavaScript経由でAPIをコールする
- 静的ファイルをCDNから配信している
Jamstackの名の通り、CDNから配信された静的ファイルからJavaScript経由でAPIを呼ぶサーバーレスな構成というのが基本形でしょう。
サーバーレスでスケールしやすく、静的ファイルのみの配信なのでセキュリティ面でもパフォーマンス面でも良いというところがJamstackの核なのだと思います。
また、Jamstackをより効果的に扱うためには、どれだけ多くの部分を静的化できるかというところにあります。
具体的な方法としては、事前に静的コンテンツを取得するAPIをコールして、コンテンツを含んだ静的ファイルを生成し、CDN経由で配信する手法が挙げられます。
このスライドも参考になります。
https://speakerdeck.com/biilmann/the-jam-stack
おわりに
弊社が開発しているmicroCMSはJamstackの一部として扱いやすいヘッドレスCMSです。
日々改善を進めていますのでご興味ある方はぜひ触ってみてください。
ご意見・ご要望は管理画面右下のチャット、公式Twitter、メールからお気軽にご連絡ください。