Jamstackで高速なプログレッシブ・ウェブ・アプリケーション（PWA）を構築する

今回はJamstackでPWAを構築した際の事例について、ご紹介いたします:loudspeaker:

プログレッシブウェブアプリケーションは、ウェブアプリケーションをモバイルデバイスに移行させたい場合に最適です。PWAへのJamstackのアプローチは、低コストでの構築と優れたスケーラビリティで最高のパフォーマンスを実現するのに役立ちました。

著者：Arkadiusz Gorecki 2019年12月3日
原文：https://bejamas.io/blog/jamstack-pwa/

![PWA.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242415/08b67415-e600-6217-366d-8de3fe083b84.jpeg)

Jamstack PWAを利用すれば、低コストでの構築と優れたスケーラビリティによるパフォーマンスの向上という点で、より効果を発揮します。

2016年11月にモバイルとタブレットのインターネット利用率がデスクトップを上回って以来、モバイルユーザーは多くの企業から注目されています。インターネットのトレンドがアプリ利用にシフトしている中、企業はアプリのようなユーザー体験をウェブサイトにももたらし、エンゲージメントを高める方法を模索していました。

それを解決したのがProgressive Web Appsです。PWAのアプローチは、モバイルデバイス上でのユーザーのウェブサイトやブランドとの関わり方を変えます。

##1. プログレッシブウェブアプリとは？

簡単に言えば、PWAはウェブサイトとアプリの中間のようなものです。PWAは、ユーザーにアプリのダウンロードを促すのではなく、ユーザーのウェブブラウザを通じてアプリのような体験をウェブサイトにもたらすことができます。

###1－1 なぜウェブサイトはPWAを使うべきなのか？

PWAは一般的なWWWサーバーからダウンロードしたHTMLをベースにしているため、技術的な観点から異なる携帯電話やOSのバージョンに合わせて調整する手間はありません。

当然ながら、PWAはモバイルアプリのような体験を提供します。つまり、より多くの機能を提供することで、ユーザーのエンゲージメントをより高めることができるのです。瞬時にロードし、ユーザーの操作に素早く応えます。

それだけではなく、オフラインでもコンテンツを閲覧することができます。

PWAでは、プッシュ通知を行うことができ、視聴者のエンゲージメントを大幅に高めることができます。

データをキャッシュするので、すべてが驚くほど高速です。読み込みに時間がかからないので、コンテンツの読み込み待ちでユーザーが離れていく心配がありません。

上記のような利点があるため、PWSは低い獲得コストで潜在的なリーチを増やし、コンバージョンを向上させると言われています。

###1－2 PWAの課題

少し前までは、クロスブラウザ対応が課題でした。現在、プログレッシブウェブアプリはChromeとOperaで完全にサポートされています。Firefoxは、PWAのほぼすべての機能をサポートしています。そしてAppleは、iOS用のSafari 11.1からようやく限定的なサポートを開始しました。これは正しい方向に向かっているとはいえ、まだまだやるべきことはたくさんあります。

また、クロスアプリケーションのログイン対応については、まだ問題がある場合もあります。iTunes StoreやGoogle Playのような、PWA用の中央ダウンロードストアが登場すれば、信頼性の向上に大きく貢献するでしょう。

##2. Jamstack PWA

この記事はケーススタディではありません。JamstackのアプローチでPWAを構築した経験から、私たちの考えを簡単に説明しています。

###2－1 私たちが作ったもの（一般的なニーズ/要求/アプリの目的）

私たちが作っていたアプリは、ブログや製品リストなどの標準的な機能を備えていなければなりませんでしたが、主な目的は、その特定のトピックに関するコミュニティを構築することでした。記事のコメント、製品のレビュー、高度なQ&Aセクション（標準的なFAQページよりもフォーラムに近い）など、ユーザーがウェブサイトのあらゆる側面（およびユーザー同士）と対話できるようにしたかったのです。

このアプリの主な機能は、ブログ、商品一覧、コミュニティパネルです。 ブログは、大量の記事を掲載し、標準的な機能とコメントシステムを備えています。 商品については、情報提供の側面を除いて、ユーザーがレビューを残せるようにしたいと考えました。 コミュニティパネルは、ユーザーがスレッドを立てたり、質問をしたり、必要な情報を得ることができる場所です。

###2－2 なぜここでJamstackを使用したのか？

従来の方法でアプリを作ると、Android用とiOS用のアプリを別々に開発し、API用のサーバー、データベース、ホスティングなどにも気を配る必要がありました。

・サードパーティのサービスを統合したり、独自のサービスをクラウド上で簡単に作成したりすることができます。
・コンテンツを可能な限りヘッドレスCMSに保持し、複数のエンドポイントから利用できるようにします
・フロントエンドとバックエンドでJavaScriptを使用します

この3つに加えて、Netlifyを利用することで、ホスティングコストを最小限に抑えることができました。アプリを他の静的サイトと同じようにホスティングして、クライアントの運用コストを削減しました。

###2－3 どのようなフレームワークやサービスを使ったのか、そしてその理由は？

最新のツールを使用したおかげで、最高のパフォーマンス、低コストでの構築、優れたスケーラビリティを実現することができました。Webサイト、ブログ、製品リストの高速化には、静的サイトジェネレータとしてNext.jsを、ヘッドレスCMSとしてContentfulを使用しました。

![pwa-stack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242415/2e110540-3c10-cba7-1ff2-5b377ad7cf6a.png)

####2－3－1 Next.js

アプリの構築にはNext.jsを使用することにしました。Next.jsは、サーバーレンダリングされたReactアプリケーションのためのフレームワークで、多くの優れたアウトオブボックスのソリューションを備えています。設定やwebpack、ルーティング、さらにはコードスプリットについても考える必要はありません。また、静的ページへのエクスポートも可能なので、Netlifyのようなホスティングやデプロイメントサービスにアプリを静的にデプロイすることもできます。

####2－3－2 Contentful

静的コンテンツ、記事、製品の管理にはContentfulを使用しました。ヘッドレスCMSとして実績があり、設定の自由度が高く、開発者や編集者が使いやすいのが特徴です。Next.jsとContentfulの組み合わせで、素晴らしい静的ウェブサイトの体験を作ることができました。Next.jsアプリは静的ファイルにエクスポートされ、ビルド時にはContentfulからすべてのエントリーを取得し、コンテンツで満たされたページをエクスポートします。これにより、送信リクエストを最小限に抑え、アプリ全体のパフォーマンスを向上させることができました。

####2－3－3 AWS

前半でもお伝えしましたが、私たちのアプリは単なるブログではなく、アプリとしての機能も必要でした。私たちはそれに命を与える必要があり、サーバーレスでそれを実現するために、AWSを採用することにしました。そのため、私たちが必要としたものはすべて揃っています。

ユーザーの画像はAmazon Simple Storage Service（Amazon S3）を使用して保存します。アプリにユーザーを追加する場合は、Cognitoを選択してください。データベースが必要ですが、ここではDynamoDBを使います。GraphQLを使ってデータにたどり着きたいと思ったら、AppSyncを使ってください。最後に、サーバーサイドで高度な操作を行う必要がありますが、Lambdaを自由に使ってください。

####2－3－4 Netlify

Netlifyは、静的なウェブサイトのためのホスティングとサーバーレスのバックエンドサービスを提供しています。私たちのプロジェクトのほとんどを支えてくれていますし、PWAにも使用できたのは素晴らしいことです。継続的インテグレーションと継続的デプロイメントサービス、無料SSL、自動ブランチデプロイ、これらの機能やその他多くの機能により、Netlifyは当社のNo.1のホスティングおよびデプロイメントオプションとなっています。

####2－3－5 Algolia

最後にアプリに追加したサードパーティのサービスはAlgoliaです。ユーザーが興味のあるコンテンツをすぐに見つけられるようにするために、アプリに検索機能を追加することは非常に重要でした。ContentfulとDynamoDBを1つのサーバーレス関数を使ってAlgoliaに接続し、すべての新しいエントリー（記事、製品、質問など）がインデックスされ、ユーザーがすぐに利用できるようにしました。

##2－4 トリッキーなパーツコメント
####2－4－1 コメント

どんな野心的なプロジェクトでもそうですが、本格的なコーディングが必要となる障害がありました。私たちのアプリは、ヘッドレスCMSのコンテンツをAPI経由で構築時に受け渡すような、シンプルなブログになる予定ではありませんでした。静的なページにも、ユーザーが作成したコンテンツを盛り込みたいと考えていました。選択肢を与えることで、ユーザーのエンゲージメントに影響を与えています。これにより、アプリ全体のパフォーマンスが向上し、ユニークなユーザーのコンテンツが検索エンジンにインデックスされるため、SEOの向上にもつながります。

ユーザー側では、受け取ったページにすべてが含まれている状態で、瞬時にコンテンツを届けたいと考えました。つまり、コメントやレビューなど、データベースに保存されているデータのロードインジケータがないのです。

さて、ではどのようにして動的コンテンツを持つ静的アプリを作ることができたのでしょうか？まず、私たちのアプリは、コメントやレビューが増えるたびに再構築することはありません。これでは、新しいコメントがすぐに表示されず、再構築後に表示されることになるため、受け入れられませんでした。この問題を解決するために、私たちはアプリをスタティックとダイナミックの両方にしました。

構築時には、利用可能なすべてのユーザー生成コンテンツが静的ページに含まれます。しかし、ユーザーがページを開いたとき、アプリはそのページで利用可能なコメントがすべて揃っているかどうかをチェックしています。そうでない場合は、コメントが新しいものに更新されます。それは、シンプルでありながら強力なアプローチです。ページ構築前に追加されたコメントは、ページに静的に追加されますが、構築後に追加されたコメントは、クライアント側でページをレンダリングする際に取得されます。

####2－4－2 Next.jsの設定

また、クライアント側でCMSからデータを取得する必要がなく、ページの切り替えが「圧倒的に速い」ことを目指しました。デフォルトでは、次のページ内のgetInitialPropsでCMSからデータを取得しているため、ユーザーがページを開いたときにCMSからコンテンツを取得してしまいます。ビルド時にすべてのCFデータをダウンロードしてJSONファイルに格納し、ローカルファイルのデータを使ってページを生成することで、Contentfulに到達することなくコンテンツを表示することができました。これにより、ページの表示が驚くほど速くなりました。

Next.jsのコード分割と配慮されたコード記述により、生成された.jsファイルには、ユーザーが現在のページで見ているコンテンツのみが含まれています。また、アプリの必要な部分を読み込むことで、パフォーマンスを向上させることもできます。

##3. JamstackビルドPWAのメリット

私たちが出会ったすべての利点を考えると、PWAの宣伝は当然のことのように思えます。このプロジェクトでは、Jamstackを全面的に採用したことで、Jamstackが提供するすべてのメリットを享受することができました。

・優れたパフォーマンス：ほとんどのコンテンツが静的なものであるため、アプリの探索/閲覧が驚くほど高速です。
・低コスト：Netlifyでアプリをホスティングすることで、コストを大幅に削減できました。「サービス付き」のオプションを使えば、お客様は使った分だけ支払うことができます。
・スケーラビリティ：エンゲージメントとリーチ（トラフィック）に応じて、迅速にスケールアップすることができます。

プログレッシブ・ウェブ・アプリケーションは、まだ主流ではないかもしれません・・・。しかし、ウェブ上でのユーザーエクスペリエンスとエンゲージメントを向上させることを目的としており、上記のようなメリットがあるため、ほとんどの企業にとって潜在的な可能性があると考えています。

最後まで読んで下さり、ありがとうございました:bow_tone1:

Jamstackに関心がある方はこちらまでお問合せください！
**株式会社ヒューマンサイエンス
https://www.science.co.jp/**