Comment faire du SSR (rendu côté serveur) avec PWA (Progressive Web App)?
D'après ce que je comprends,
Le runtime SSR chargera la page et exécutera les scripts nécessaires pour charger les données sur la page. Retourne ensuite le html rendu. Ceci est important pour les robots d'exploration Web qui n'exécuteront pas le javascript et les navigateurs sans script. Au moins, la première impression sera utilisable.
Entre autres, PWA nécessite d'avoir un Shell, qui sera mis en cache et les données viendront après. Cela signifie que même si l'utilisateur est hors ligne, le Shell sera chargé.
Donc, si nous pré-rendons les données, comment peut-on mettre en cache le Shell séparément des données?
Si vous souhaitez uniquement mettre en cache Shell à partir de la vue SSR pré-rendue avec les données initiales, vous devez fournir deux vues:
/view-url
avec des données de SSR/view-url?shell
avec uniquement la version Shell, sans données (vous pouvez changer la logique de l'url-requête par exemple en-tête de demande).Lors de la première utilisation de l'utilisateur, saisissez /view-url
vous envoyez 1. la version et le cache dans Service Worker /view-url?shell
. Lorsque l'utilisateur revient à /view-url
vous lui envoyez /view-url?shell
à partir du cache Service Worker en faisant quelque chose comme ceci:
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))
);
});
Le point clé ici est que vous modifiez la demande d'origine /view-url
à /view-url?shell
dans Service Worker!
Si vous voulez en savoir plus sur cette technique, j'ai écrit un article sur ce problème Comment combiner PWA et le rendu isomorphe (SSR)?
La stratégie consiste à servir le premier chargement de page à l'aide de SSR et toutes les navigations de page suivantes à l'aide du shell d'application mis en cache. SSR renvoie un html différent pour différentes pages, nous pouvons donc spécifier un chemin spécial comme /app-Shell
pour récupérer un squelette html pour le rendu côté client.
Si vous voulez en savoir plus à ce sujet, vous pouvez vous référer à mon article Comment transformer un SPA côté serveur React SPA en PWA .
Vous pouvez conserver le shell dans un dossier séparé et la page rendue dans un autre, afin qu'ils aient portée différente que vous pouvez définir dans Service Worker pour définir ce qui doit être mis en cache et ce qui ne doit pas être mis en cache.