PWA(プログレッシブウェブアプリ)でSSR(サーバー側レンダリング)を実行するにはどうすればよいですか?
私が理解していることから、
SSRランタイムはページを読み込み、ページにデータを読み込むために必要なスクリプトを実行します。次に、レンダリングされたHTMLを返します。これは、JavaScriptを実行しないWebクローラーや、スクリプトなしのブラウザーでは重要です。少なくとも第一印象は使えるでしょう。
特に、PWAにはシェルが必要です。シェルはキャッシュされ、データはその後に送信されます。つまり、ユーザーがオフラインであっても、シェルは読み込まれます。
では、データを事前にレンダリングしている場合、シェルをデータとは別にキャッシュするにはどうすればよいでしょうか。
事前レンダリングされたSSRビューからのシェルのみを初期データとともにキャッシュする場合は、2つのビューを提供する必要があります。
/view-url
SSRからのデータ/view-url?shell
データなしのシェルバージョンのみ(ロジックをurl-queryからリクエストヘッダーなどに変更できます)。ユーザーが初めて/view-url
を入力すると、バージョンを送信し、Service Worker /view-url?shell
にキャッシュします。ユーザーが/view-url
に戻ってきたら、次のようにしてService Workerキャッシュから/view-url?shell
を送信します。
const CACHE_NAME = 'cache-token';
const staticUrlsToCache = ['/style.css', '/script.js', '/logo.png'];
const shellUrlsToCache = ['/view-url'];
const urlsToCache = [
...staticUrlsToCache,
shellUrlsToCache.map(url => `${url}?shell`),
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.addAll(urlsToCache))
);
});
self.addEventListener('fetch', event => {
let request = event.request;
const shellUrl = shellUrlsToCache.find(url => request.url.endsWith(url));
if (shellUrl) {
// here is real magic!
request = new Request(`${shellUrl}?shell`);
}
event.respondWith(
caches.match(request).then(response => response || fetch(request))
);
});
ここで重要なのは、Service Workerで元のリクエスト/view-url
を/view-url?shell
に変更することです。
この手法の詳細を読みたい場合は、この問題について記事を書きました PWAと同形レンダリング(SSR)を組み合わせる方法は?
戦略は、SSRを使用して最初のページの読み込みと、キャッシュされたアプリシェルを使用して以降のすべてのページナビゲーションを提供することです。 SSRはページごとに異なるhtmlを返すため、/app-Shell
のような特別なパスを指定して、クライアント側レンダリング用のスケルトンhtmlをフェッチできます。
詳細については、私の記事を参照してください サーバー側でレンダリングされる方法React SPAをPWAに変換する方法 。
シェルを別のフォルダーに保持し、レンダリングされたページを別のフォルダーに保持できるので、シェルは 別のスコープ を持ち、キャッシュするものとキャッシュしないものをService Workerで設定できます。