From c183c8f9310bb72a919364326bcd03c124cb378b Mon Sep 17 00:00:00 2001 From: Ramon Date: Sun, 19 Jul 2026 13:43:32 +0200 Subject: [PATCH] perf: opstart-fetches /auth/me en /me/data parallel i.p.v. serieel (v0.4.31-beta) - Beide verzoeken hangen alleen af van dezelfde sessie-cookie, niet van elkaars antwoord - ze werden tot nu toe na elkaar aangeroepen (hydrateFromServer() startte pas na een voltooide /auth/me), wat een hele round-trip extra kost bij elke opstart voor staf/thuisgebruikers. - app.js vraagt ze nu tegelijk op via Promise.allSettled; hydrateFromServer() krijgt het /me/data-resultaat optioneel meegegeven i.p.v. het zelf (opnieuw) op te halen. Voor een leerling/ouder wordt dat resultaat genegeerd (zij krijgen sowieso geen whiteboard-data) - nooit verspild werk, soms ongebruikt, wat de server niet meer kost dan de bestaande losse aanroep die er toch al was. - De twee andere hydrateFromServer()-aanroepen (na inloggen, na een save-conflict) geven bewust niets mee en halen gewoon vers op, zoals voorheen - alleen de allereerste opstart kan dit parallelliseren. - Geverifieerd met de volledige testsuite (112/112) en drie losse boot-scenario's in de sandbox (gast/staf/leerling): in alle drie komen /auth/me en /me/data binnen ~1ms van elkaar aan (voorheen serieel), en blijft het bestaande gedrag (gast blijft gast, staf krijgt het bord, leerling krijgt de afgeschermde weergave) exact hetzelfde. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_014EPxzBVRXZZnBPvSAaPAbJ --- VERSION | 2 +- public/js/app.js | 13 ++++++++++--- public/js/core.js | 12 +++++++++--- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/VERSION b/VERSION index 96ea3ee..48e07bc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.30-beta \ No newline at end of file +0.4.31-beta \ No newline at end of file diff --git a/public/js/app.js b/public/js/app.js index 70e1180..18d6841 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -85,10 +85,17 @@ updateEmptyHint(); (async function(){ updateBoardsUI(); try{ - const me = await api("/auth/me"); - currentUser = me.user; + /* /auth/me en /me/data hangen allebei alleen af van dezelfde sessie-cookie, + niet van elkaars antwoord - serieel wachten (eerst wie-ben-ik, dan pas + mijn-data ophalen) kost een hele round-trip voor niets. Parallel + opvragen en het tweede antwoord meegeven aan hydrateFromServer() + (die het gewoon negeert voor een leerling/ouder, zie daar) scheelt die + round-trip in het veelvoorkomende geval (staf/thuisgebruiker). */ + const [meResult, dataResult] = await Promise.allSettled([api("/auth/me"), api("/me/data")]); + if(meResult.status !== "fulfilled") throw meResult.reason; + currentUser = meResult.value.user; updateUserUI(); - await hydrateFromServer(); + await hydrateFromServer(dataResult.status === "fulfilled" ? dataResult.value : null); }catch(e){ resetToGuest(); } diff --git a/public/js/core.js b/public/js/core.js index 5e72a79..1241f27 100644 --- a/public/js/core.js +++ b/public/js/core.js @@ -2,7 +2,7 @@ "use strict"; /* version — shown until /api/version resolves (or if the fetch fails, e.g. offline). Kept in sync by hand with the VERSION file at the repo root on every release. */ -const VERSION = "0.4.30-beta"; +const VERSION = "0.4.31-beta"; (function(){ const tag = document.getElementById("verTag"); tag.textContent = "v"+VERSION; @@ -887,7 +887,13 @@ function persistWords(){ function generalExtraFromData(data){ return (data && data.generalExtra) ? data.generalExtra : {nl:[], en:[]}; } -async function hydrateFromServer(){ +/* prefetchedData: alleen gebruikt door de opstart-boot in app.js, die /me/data + al parallel met /auth/me heeft opgehaald (zie daar) i.p.v. serieel te + wachten - een leerling/ouder gebruikt het resultaat toch niet (zie de twee + vroege returns hieronder), dus dat verzoek is nooit verspild werk, alleen + soms ongebruikt. Elke andere aanroep (na inloggen, na een save-conflict) + geeft niets mee en haalt gewoon vers op, zoals voorheen. */ +async function hydrateFromServer(prefetchedData){ /* schoolleerlingen hebben geen eigen borden - zij zien enkel wat de leerkracht heeft toegewezen (zie pupil.js), nooit het whiteboard. Thuiskinderen (leerling zonder school, ouderportaal) vallen hier expres @@ -911,7 +917,7 @@ async function hydrateFromServer(){ } stopPupilView(); stopParentView(); - const res = await api("/me/data"); + const res = prefetchedData || await api("/me/data"); const d = res.data || {}; DATA_REV = typeof res.rev === "number" ? res.rev : 0; THEMES = themesFromData(d);