Perf: Prioritäts-Seiten pre-cache + Stale-While-Revalidate + Background-Warm-up (SW by-v981)
This commit is contained in:
parent
78f3077317
commit
1a8716b0b2
3 changed files with 48 additions and 8 deletions
|
|
@ -408,7 +408,7 @@ async def serve_media(path: str, request: _Request):
|
||||||
raise _HE(404, "Nicht gefunden.")
|
raise _HE(404, "Nicht gefunden.")
|
||||||
return _media_response(filepath)
|
return _media_response(filepath)
|
||||||
|
|
||||||
APP_VER = "980" # muss mit APP_VER in app.js übereinstimmen
|
APP_VER = "981" # muss mit APP_VER in app.js übereinstimmen
|
||||||
|
|
||||||
@app.get("/.well-known/assetlinks.json")
|
@app.get("/.well-known/assetlinks.json")
|
||||||
async def assetlinks():
|
async def assetlinks():
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
Router, State-Management, Navigation, Initialisierung.
|
Router, State-Management, Navigation, Initialisierung.
|
||||||
============================================================ */
|
============================================================ */
|
||||||
|
|
||||||
const APP_VER = '980'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
const APP_VER = '981'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||||
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
|
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
|
||||||
const IS_STAGING = location.hostname === 'staging.banyaro.app';
|
const IS_STAGING = location.hostname === 'staging.banyaro.app';
|
||||||
// Cache-Bust-Parameter nach Update-Reload sofort entfernen
|
// Cache-Bust-Parameter nach Update-Reload sofort entfernen
|
||||||
|
|
@ -1140,6 +1140,19 @@ const App = (() => {
|
||||||
window.App = App; // Worlds kann App.navigate() aufrufen
|
window.App = App; // Worlds kann App.navigate() aufrufen
|
||||||
|
|
||||||
// App starten
|
// App starten
|
||||||
|
// Prioritäts-Seiten im Hintergrund vorladen (3s nach Start, damit Hauptinhalt nicht blockiert)
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!('caches' in window)) return;
|
||||||
|
['admin','erste-hilfe','diary','map','walks','routes','poison','lost'].forEach(page => {
|
||||||
|
const key = `Page_${page.replace(/-/g,'_')}`;
|
||||||
|
if (!window[key]) {
|
||||||
|
fetch(`/js/pages/${page}.js?v=${APP_VER}`).catch(() => {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 3000);
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
App.init();
|
App.init();
|
||||||
if (IS_STAGING) {
|
if (IS_STAGING) {
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,28 @@
|
||||||
Offline-Cache + Push Notifications + Tile-Cache
|
Offline-Cache + Push Notifications + Tile-Cache
|
||||||
============================================================ */
|
============================================================ */
|
||||||
|
|
||||||
const CACHE_VERSION = 'by-v980';
|
const CACHE_VERSION = 'by-v981';
|
||||||
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
||||||
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
|
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
|
||||||
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache
|
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache
|
||||||
|
|
||||||
|
// Prioritäts-Seiten: werden pre-gecacht + Stale-While-Revalidate
|
||||||
|
const PRIORITY_PAGES = [
|
||||||
|
'/js/pages/admin.js',
|
||||||
|
'/js/pages/erste-hilfe.js',
|
||||||
|
'/js/pages/diary.js',
|
||||||
|
'/js/pages/map.js',
|
||||||
|
'/js/pages/walks.js',
|
||||||
|
'/js/pages/routes.js',
|
||||||
|
'/js/pages/poison.js',
|
||||||
|
'/js/pages/lost.js',
|
||||||
|
];
|
||||||
|
|
||||||
// index.html wird NICHT pre-gecacht (immer Network-First)
|
// index.html wird NICHT pre-gecacht (immer Network-First)
|
||||||
const STATIC_ASSETS = [
|
const STATIC_ASSETS = [
|
||||||
'/css/design-system.css?v=700',
|
'/css/design-system.css?v=980',
|
||||||
'/css/layout.css?v=700',
|
'/css/layout.css?v=980',
|
||||||
'/css/components.css?v=700',
|
'/css/components.css?v=980',
|
||||||
'/icons/phosphor.svg',
|
'/icons/phosphor.svg',
|
||||||
'/js/api.js',
|
'/js/api.js',
|
||||||
'/js/ui.js',
|
'/js/ui.js',
|
||||||
|
|
@ -22,6 +34,7 @@ const STATIC_ASSETS = [
|
||||||
'/css/MarkerCluster.Default.css',
|
'/css/MarkerCluster.Default.css',
|
||||||
'/manifest.json',
|
'/manifest.json',
|
||||||
'/icons/icon-192.png',
|
'/icons/icon-192.png',
|
||||||
|
...PRIORITY_PAGES,
|
||||||
];
|
];
|
||||||
|
|
||||||
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
||||||
|
|
@ -297,7 +310,21 @@ self.addEventListener('fetch', event => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CSS, Core-JS + Seiten-Module: immer Network-First — damit iOS nie veraltete Versionen cached
|
// Prioritäts-Seiten: Stale-While-Revalidate — sofort aus Cache, im Hintergrund aktualisieren
|
||||||
|
if (PRIORITY_PAGES.includes(url.pathname)) {
|
||||||
|
event.respondWith(
|
||||||
|
caches.open(CACHE_STATIC).then(async cache => {
|
||||||
|
const cached = await cache.match(event.request, { ignoreSearch: true });
|
||||||
|
const netFetch = fetch(event.request)
|
||||||
|
.then(res => { if (res.ok) cache.put(event.request, res.clone()); return res; })
|
||||||
|
.catch(() => null);
|
||||||
|
return cached ?? (await netFetch) ?? new Response('', { status: 503 });
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CSS, Core-JS + übrige Seiten-Module: Network-First — damit iOS nie veraltete Versionen cached
|
||||||
if (url.pathname.startsWith('/css/') || url.pathname.startsWith('/js/pages/')
|
if (url.pathname.startsWith('/css/') || url.pathname.startsWith('/js/pages/')
|
||||||
|| url.pathname.startsWith('/js/app.js') || url.pathname.startsWith('/js/ui.js')
|
|| url.pathname.startsWith('/js/app.js') || url.pathname.startsWith('/js/ui.js')
|
||||||
|| url.pathname.startsWith('/js/api.js') || url.pathname.startsWith('/js/worlds.js')) {
|
|| url.pathname.startsWith('/js/api.js') || url.pathname.startsWith('/js/worlds.js')) {
|
||||||
|
|
@ -310,7 +337,7 @@ self.addEventListener('fetch', event => {
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
})
|
})
|
||||||
.catch(() => caches.match(event.request)
|
.catch(() => caches.match(event.request, { ignoreSearch: true })
|
||||||
.then(cached => cached || new Response('', { status: 503 })))
|
.then(cached => cached || new Response('', { status: 503 })))
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue