見出し画像

Jamstackで大規模ECサイトを構築するのに適したコンポーネントを考察してみた

この記事は「株式会社メンバーズ Jamstack研究会主催 Advent Calendar 2023」の25日目の記事です。


案件で大規模なECサイトの運用、改修を行っているので、流行りのJamstack構成でECサイトを構築するのに適したコンポーネント構成を考察します。
ほとんどは個人の主観による意見なので、参考程度にしてもらえればと思います。また、ここで紹介するフレームワークなどは2023年12月時点でのバージョンについて記述しています。

Jamstackとは

ご存知の方も多いとは思いますが、JamstackはWeb開発の手法の一つで、速くて安全なWebサイトを構築するために設計されています。Jamstackの「JAM」は、JavaScript、API、Markupの頭文字をとったもので、それぞれの役割について簡単に説明します。

  1. JavaScript:これはWebサイトにインタラクティブ性を追加するためのプログラミング言語です。ユーザーがWebサイトと対話する際に使用します。(例:ボタンをクリックしたときの動作など)。

  2. API:APIは「Application Programming Interface」の略で、異なるソフトウェアやサービス間で情報を交換するためのルールや仕組みです。例えば、天気情報やユーザーのデータなどを外部のサービスからWebサイトに取り込むときに使用します。

  3. Markup:これはWebサイトの構造を定義するためのコード(HTMLなど)です。Webサイトのテキスト、画像、リンクなどの配置やフォーマットを指定します。

Jamstackの特徴は、これらの要素が事前に生成され、Webサイトが訪問者に提供される際には静的なファイルとして配信される点です。これにより、従来の動的なサーバー生成型のWebサイトよりも速く、安全で、トラフィック(帯域利用量)の増加にも柔軟に対応できるというメリットがあります。

ECサイトの機能について

ECサイトはその性質上、一般的なWebサイトと比べて、より複雑な機能、より高いレベルのセキュリティを要求されます。必要になる機能は多岐に渡りますが、一例として以下のものが挙げられると思います。

  1. ユーザー登録・ログイン機能:ユーザーが個人情報を登録し、アカウントを作成できる機能。ログインすることで、購入履歴の確認や個人設定の変更(マイページ)などが可能になります。

  2. 商品カタログ・検索機能:販売する商品の情報をカタログ形式で表示する機能。ユーザーが商品を検索しやすくするために、キーワード検索、カテゴリ分け、フィルタリング機能などが必要です。

  3. ショッピングカート機能:ユーザーが購入する商品を仮に保存する機能。カート内の商品は購入前に数量の変更や削除が可能です。

  4. 注文・決済機能:商品の注文と決済を行う機能。クレジットカード、電子マネー、代引きなど、複数の支払い方法を提供することが望ましいです。

  5. 顧客サービス機能:問い合わせやアフターサポートを提供する機能。FAQセクション、チャットサポート、メールフォームなどが含まれます。

  6. セキュリティ機能:ユーザーの個人情報や取引情報を保護するための機能。SSL暗号化、不正アクセス対策、データバックアップなどが必要です。

また、運営者側(バックエンド)においては在庫管理や配送管理の機能も必要になってくるので、構築難易度は高めになります。
しかし、各機能を実装するために活用できるサードパーティ製のサービスやAPIは多数存在しています。例えば、注文・決済機能であれば、

  • Stripe: オンラインでのクレジットカード決済処理を簡単に行えるようにするAPIです。

  • PayPal: グローバルな決済プラットフォームで、広範な支払いオプションを提供しています。

などが候補に挙がります。これらを利用することで、構築をある程度簡易にすることは可能です。

Jamstack構成での課題

大規模なECサイトを構築する上で、Jamstackで課題になりそうなことを以下の3つにまとめてみました。

  1. セキュリティと決済処理:Jamstackでは、クライアントサイドでの処理が多くなるため、決済情報などの機密データを扱う場合、これらのデータが露出したり、悪意のある第三者によって操作されるリスクがあります。

  2. リアルタイムデータの扱い:ユーザーがアクティブにインタラクションする機能(リアルタイムの商品検索やフィルタリング)を実装するためにはクライアントサイドのJavaScriptの実行が必要になり、パフォーマンスに影響を与える可能性があります。

  3. ビルド時間:数万から数百万に及ぶ商品データベース(ページ)を扱う場合、静的サイトジェネレータのビルド時間が問題になる可能性があります。

ECサイトはサードパーティサービスや外部のAPIを多用することになりますが、Jamstackの特性であるパフォーマンスの高さを損なわないように、これらの問題に対応できるコンポーネントを選定していく必要があります。

バックエンドとフロントエンドのフレームワーク

大規模なECサイトでは、動的なコンテンツとユーザーインタラクションが中心となります。Jamstackは基本的に静的なサイトで、これらの実装を行うためには、クライアントサイドレンダリング (CSR)やサーバーサイドレンダリング (SSR)が必要になってきます。

ヘッドレスCMSの選定(バックエンド)

ヘッドレスCMSは、コンテンツをAPI経由で提供し、フロントエンドの表示に関する制限がないCMSです。この仕様がJamstackの特性にマッチしているため、データモデルの構築やデータベースの設定にはヘッドレスCMSを利用します。選定の基準として、「スケーラビリティ」、「サードパーティサービスとの互換性」、「セキュリティ」が重要だと考えます。

スケーラビリティ」は訪問者数や商品数の増減に伴ってスケールすることで、需要の変動に合わせて柔軟に対応でき、サイトのパフォーマンスを維持するのに役立ちます。
サードパーティサービスとの互換性」は在庫管理システム、決済ゲートウェイ、カスタマーレビューシステムなど、ECサイトは外部APIやサードパーティサービス(例:Stripe、PayPal)に依存するので、統合が容易になることは大きなメリットです。
セキュリティ」はどのようなサービスでも重要ですが、顧客データや金融情報を扱うECサイトにとっては特に重要です。
これらの項目に優れつつ、総合的な性能が高いと感じたヘッドレスCMSは以下になります。

  • Contentful

    • スケーラビリティ:Google Cloud Platform をベースにしたクラウドインフラストラクチャを提供しており、大量のコンテンツでも高速に配信することができます。また、ContentfulのAPIは、クエリ結果をキャッシングするために最適化されており、特にGraphQL APIでは、クエリの結果をキャッシュしやすい形式で提供します。

    • サードパーティサービスとの互換性:RESTful APIとGraphQL APIを提供し、多種多様なサードパーティサービスとの統合が可能です。また、豊富なマーケットプレイスがあり(Contentful Marketplace)、多くの既存のアプリやカスタムアプリを統合できます。

    • セキュリティ:データを暗号化して保存し、データの転送時にもHTTPSを利用し、安全性を担保しています。細かいアクセス権限設定が可能で、ロールベースのアクセスコントロールを提供します。これにより、不要なデータへのアクセスを防止できます。

  • Sanity

    • スケーラビリティ:リアルタイムでのコンテンツ更新をサポートしており、サイトの成長やユーザー数の増加に応じて、迅速なコンテンツ配信と更新が行えます。GROQという独自のクエリ言語を採用しており、データ処理とクエリの柔軟性に優れており、大量のデータや複雑なクエリにも対応可能です。

    • サードパーティサービスとの互換性:RESTful APIとGraphQL APIを提供し、多種多様なサードパーティサービスとの統合が可能です。リアルタイムのコンテンツ編集とコラボレーション機能を提供するため、複数のユーザーやシステムが同時にコンテンツを更新し、外部サービスと同期することが可能です。

    • セキュリティ:データを暗号化して保存し、データの転送時にもHTTPSを利用し、安全性を担保しています。細かいアクセス権限設定が可能で、ロールベースのアクセスコントロールを提供します。これにより、不要なデータへのアクセスを防止できます。

  • Strapi

    • スケーラビリティ:自己ホストでカスタマイズが可能なため、需要に応じてスケールアップしやすいです。使用するインフラやデータベースの設定に依存しますが、適切に設定された場合、高いパフォーマンスを提供できます。

    • サードパーティサービスとの互換性:RESTful APIとGraphQL APIを提供し、多種多様なサードパーティサービスとの統合が可能です。また、オープンソースであるため、コミュニティのサポートを受けながらカスタム機能やプラグインを追加できます。

    • セキュリティ:自己ホストであるため、データの暗号化やセキュリティ対策は開発者自身で設定する必要がありますが、適切に設定できればより高いセキュリティを実現できます。HTTPSの使用など基本的なセキュリティは実装されています。

ContentfulSanityはクラウドベースであるため、自動スケーリングなどに対応しており、管理は容易になります。これらの要件を最も総合的に満たすのは、おそらくContentfulです。
Strapiに関しては自己ホストでカスタマイズ次第なところはありますが、紹介にも書いた通り、適切に設定できれば、潜在的なポテンシャルは一番高いと感じています。

Contentful/Sanity/Strapiの機能比較表

$$
\begin{array}{|l|c|c|c|}
\hline
\textbf{機能 / CMS} & \textbf{Contentful} & \textbf{Sanity} & \textbf{Strapi} \\
\hline
\text{APIタイプ} & \text{RESTful \& GraphQL} & \text{RESTful \& GraphQL} & \text{RESTful \& GraphQL} \\
\hline
\text{カスタムコンテンツモデル} & \text{あり} & \text{あり} & \text{あり} \\
\hline
\text{リアルタイム編集} & \text{なし} & \text{あり} & \text{なし} \\
\hline
\text{アセット管理} & \text{高度} & \text{高度} & \text{基本} \\
\hline
\text{バージョン管理} & \text{あり} & \text{あり} & \text{あり} \\
\hline
\text{マルチ言語サポート} & \text{あり} & \text{あり} & \text{あり} \\
\hline
\text{ロールベースのアクセス制御} & \text{あり} & \text{あり} & \text{あり} \\
\hline
\text{カスタムプラグイン} & \text{限定的} & \text{あり} & \text{あり} \\
\hline
\text{Webhooks} & \text{あり} & \text{あり} & \text{あり} \\
\hline
\text{カスタマイズ可能なUI} & \text{あり} & \text{あり} & \text{あり} \\
\hline
\text{データエクスポート/インポート} & \text{あり} & \text{あり} & \text{あり} \\
\hline
\text{SEO対応} & \text{あり} & \text{あり} & \text{あり} \\
\hline
\text{ホスティング} & \text{クラウド} & \text{自己ホスティングまたはクラウド} & \text{自己ホスティングまたはクラウド} \\
\hline
\text{無料プラン} & \text{あり} & \text{あり} & \text{あり} \\
\hline
\text{コミュニティサポート} & \text{あり} & \text{あり} & \text{あり} \\
\hline
\text{セキュリティ} & \text{高度} & \text{高度} & \text{基本} \\
\hline
\text{モバイルアプリ} & \text{あり} & \text{なし} & \text{なし} \\
\hline
\end{array}
$$

静的サイトジェネレーターの選定(フロントエンド)

静的サイトジェネレーターは、その名の通り、Webサイトのコンテンツを静的HTMLファイルとして生成するツールです。これらのHTMLファイルは、サーバー上で事前に生成され、その後クライアント(ユーザーのブラウザ)に配信されます。Jamstackと親和性が高く、多くのヘッドレスCMSは静的サイトジェネレーターと簡単に統合できるため、フロントエンド構築にはこちらを使用します。
選定の基準として、「メンテナンス性」、「SSRへの対応」、「ビルドパフォーマンス」が重要だと考えます。

メンテナンス性」は、長期的に運用していくため、開発者の入れ替わりや追加をした際に、フレームワーク関連のコミュニティが活発でドキュメントが多く、学習がしやすい(引き継ぎがしやすい)ことが求められます。また、コードの変更、新機能の追加、バグ修正なども定期的に発生するため、作業を効率的かつ迅速に行えることが望ましいです。
SSRへの対応」は、製品の在庫状況のリアルタイム更新やユーザーの行動に基づくレコメンデーションシステムなど動的な機能が求められるので、SSRをサポートしており、且つページ単位で柔軟にレンダリング方法をSSGに切り替えられることが望ましいです。
ビルドパフォーマンス」は、数千から数万ページにも及ぶ可能性があり、ビルドプロセスが遅くなる可能性が高く、全体的な効率に影響します。コンテンツの更新や機能の追加を迅速に行うことを可能にすることで、市場への対応速度の向上が期待できます。
これらの項目に優れつつ、総合的な性能が高いと感じた静的サイトジェネレーターは以下になります。

  • Next.js(Next13以上)

    • メンテナンス性:Reactベースの静的サイトジェネレーターで、豊富なコミュニティと広範なドキュメントに支えられ、継続的なアップデートが行われています。React with TypeScriptはデータの単方向性やタイプチェックによって、テスタビリティが高く、品質を保ちやすいです。

    • SSRへの対応:SSRをサポートしており、ハイブリッドレンダリングにも対応しています。各ページのレンダリング方法を個別に選択でき、getStaticPropsgetServerSidePropsといった関数を使って、ファイル(ページ)ごとにSSGかSSRを選択できます。

    • ビルドパフォーマンス:インクリメンタルスタティックリジェネレーション(ISR)という機能を搭載しており、ページを定期的にバックグラウンドで再生成し、古いページを新しいものに置き換えることができます。これによりビルド時にすべてのページを一度に生成する必要がなくなります。

  • Nuxt.js(Nuxt3以上)

    • メンテナンス性:Vueベースの静的サイトジェネレーターで、豊富なコミュニティと広範なドキュメントに支えられ、継続的なアップデートが行われています。HTML、CSS、JavaScriptが明確に分離されているため、コードの整理や管理がしやすいです。

    • SSRへの対応:SSRをサポートしており、ハイブリッドレンダリングにも対応しています。設定ファイル(nuxt.config.ts)で各ルートにルールを指定することで、特定のディレクトリやファイルに対してSSGかSSRを選択できます。

    • ビルドパフォーマンス:ビルド高速化用のオプションがあり、複数スレッドのビルドによる高速化や、モジュールをキャッシュ管理することにより2回目以降のビルドを高速化することが可能です。
      ※Nuxt.jsも現時点ではNetlifyVercel環境のみですが、Nuxt3でISG/ISRをサポートするようになっています。

それぞれReactとVueをベースにしたフレームワークであり、どちらもモダンなWeb開発において多くの機能を提供しています。
VueのコミュニティはReactに比べると若干小さいことがあり、利用可能なリソースやライブラリが限られることがあるので、総合力で言えばNext.jsのほうが高いと感じています。

Next.js/Nuxt.jsの機能比較表

$$
\begin{array}{|l|c|c|}
\hline
\textbf{機能 / フレームワーク} & \textbf{Next.js} & \textbf{Nuxt.js} \\
\hline
\text{基本言語} & \text{JavaScript (React)} & \text{JavaScript (Vue)} \\
\hline
\text{サーバーサイドレンダリング (SSR)} & \text{あり} & \text{あり} \\
\hline
\text{スタティックサイト生成 (SSG)} & \text{あり} & \text{あり} \\
\hline
\text{ホットリローディング} & \text{あり} & \text{あり} \\
\hline
\text{自動コード分割} & \text{あり} & \text{あり} \\
\hline
\text{APIルート} & \text{あり} & \text{プラグインを通じて} \\
\hline
\text{TypeScriptサポート} & \text{あり} & \text{あり} \\
\hline
\text{ルーティング} & \text{ファイルベース} & \text{ファイルベース} \\
\hline
\text{SEO最適化} & \text{あり} & \text{あり} \\
\hline
\text{モジュールシステム} & \text{あり} & \text{あり} \\
\hline
\text{データフェッチング} & \text{あり} & \text{あり} \\
\hline
\text{プラグインアーキテクチャ} & \text{あり} & \text{あり} \\
\hline
\text{カスタムビルドコンフィグ} & \text{あり} & \text{あり} \\
\hline
\text{インターナショナライゼーション} & \text{コミュニティプラグインを通じて} & \text{あり} \\
\hline
\text{ストア管理 (ステート管理)} & \text{ReduxやContextなどのライブラリを通じて} & \text{Vuexを使用} \\
\hline
\text{モバイルアダプテーション} & \text{React Nativeとの互換性} & \text{Vue NativeやQuasarなどのオプションを通じて} \\
\hline
\text{デバッグサポート} & \text{あり} & \text{あり} \\
\hline
\text{パフォーマンス最適化} & \text{あり} & \text{あり} \\
\hline
\text{コミュニティとサポート} & \text{大規模} & \text{大規模} \\
\hline
\end{array}
$$

Hosting(ホスティング)サービス、CI/CDツールについて

Hosting、CI/CDについてはインフラの領域になりますので、直接サイトの構築に関わる部分ではないですが、開発プロセスの効率化と品質向上には大きく影響します。

Hosting

Webサイトやアプリケーションを動かすための土台になります。インターネット上で何かを公開するためには、そのデータを保存し、アクセス可能にする場所が必要です。Hostingサービスは、その場所を提供し、Webサイトやアプリケーションがインターネットを通じていつでもどこからでもアクセスできるようにします。

CI/CD

ソフトウェア開発のプロセス(テストなど)を自動化するための方法です。

  • CI(継続的インテグレーション): 開発者が新しいコード変更を頻繁にメインのコードベースに統合するプロセスです。これにより、コードの変更が小さくなり、エラーを早期に発見しやすくなります。

  • CD(継続的デリバリー/デプロイメント): CIのプロセスをさらに進め、新しいコード変更を自動的にテストして本番環境に配信するプロセスです。デリバリーでは、本番環境へのリリース前に手動での承認が必要ですが、デプロイメントでは全てのプロセスが自動で行われます。

CI/CDツールはヘッドレスCMSと静的サイトジェネレーターの間を繋いで補完するもので、ヘッドレスCMSが更新されると、フックされたCI/CDが起動して、静的サイトジェネレータを使用してHostingに静的ファイルをデプロイし、Hostingサービスが静的サイトを公開するという流れになります。

HostingサービスとCI/CDツールは使用することを推奨しますが、両方の機能を提供するプラットフォームが存在します。その中でもJamstackとの相性が良いと個人的に思うものはNetlifyVercelです。両者共にJamstackなWebサイトのホスティングに特化しており、GitHub、GitLab、Bitbucketといったバージョン管理システムとも統合が可能です。

Netlify/Vercelの機能比較表

$$
\begin{array}{|l|c|c|}
\hline
\textbf{機能 / プラットフォーム} & \textbf{Netlify} & \textbf{Vercel} \\
\hline
\text{デプロイメントタイプ} & \text{スタティックサイト、サーバーレスアプリ} & \text{スタティックサイト、サーバーレスアプリ} \\
\hline
\text{ビルドの自動化} & \text{あり} & \text{あり} \\
\hline
\text{プレビュー機能} & \text{あり} & \text{あり} \\
\hline
\text{カスタムドメイン} & \text{あり} & \text{あり} \\
\hline
\text{SSL証明書} & \text{無料} & \text{無料} \\
\hline
\text{CDN} & \text{グローバル} & \text{グローバル} \\
\hline
\text{リアルタイムログ} & \text{あり} & \text{あり} \\
\hline
\text{APIゲートウェイ} & \text{あり} & \text{あり} \\
\hline
\text{スプリットテスティング} & \text{あり} & \text{あり} \\
\hline
\text{バックエンドサポート} & \text{限定的(サーバーレス関数)} & \text{あり(サーバーレス関数)} \\
\hline
\text{データベース統合} & \text{限定的} & \text{限定的} \\
\hline
\text{ユーザー認証} & \text{あり(Identityサービスを通じて)} & \text{限定的} \\
\hline
\text{アセット最適化} & \text{あり} & \text{あり} \\
\hline
\text{コミュニティサポート} & \text{あり} & \text{あり} \\
\hline
\text{無料プラン} & \text{あり} & \text{あり} \\
\hline
\text{カスタムプラグイン} & \text{あり} & \text{限定的} \\
\hline
\text{チーム協力ツール} & \text{あり} & \text{あり} \\
\hline
\end{array}
$$

まとめ

Jamstackは、静的サイトの生成に特化したアーキテクチャなので、リアルタイムの更新が多いサイトでは、配信に関連するパフォーマンスやスケーラビリティの問題など、様々な点に気をつける必要があります。

大規模ECサイトは元々構築の難易度が高いのに加えて、Jamstackは比較的専門性が高い技術になりますので、静的サイトジェネレーターやヘッドレスCMS、サーバーレス関数などに慣れていない開発者にとっては厳しい開発になることになると思います。コスト効率が良いJamstackではありますが、多くのサードパーティサービスを使用すると、それらのサービスのコストが積み重なって意外と高くつく可能性も否定できません。

大規模ECサイトにおいて現状は、LP(ランディングページ)、ブログ、FAQ、ヘルプセクションなど限コンテンツが頻繁に変更されないページをヘッドレスCMSで管理し、商品詳細や商品一覧は従来型のCMSで管理するのが無難かもしれません。商品情報が定期的にしか更新されないような小規模なECサイトであれば、ヘッドレスCMSで商品一覧も管理しても問題無いと思います。

将来的にJamstackアーキテクチャと分散型データベースを統合するなどで、大規模なデータ処理と高速なデータアクセスを実現できれば、Jamstackで大規模ECサイトをより簡単に構築できるかもしれません。将来の技術に期待ですね。今回の記事が、ECサイト構築の参考になれば幸いです。

この記事が気に入ったらサポートをしてみませんか?