perf: reuse locals.session from hook instead of re-awaiting locals.auth()

hooks.server.ts already awaits auth() once and stores the result on
locals.session. In-scope loaders (recipe list + filter views, rosary,
prayers, calendar — already done — and fitness stats) were awaiting
locals.auth() a second time per request.

Switched to the existing `locals.session ?? await locals.auth()` pattern
so the hook's result is reused. Also pulls session out of Promise.all
legs since it's now synchronous when the hook ran.

Scope: loaders only — actions, /admin, /edit, /add intentionally skipped.
This commit is contained in:
2026-04-23 15:06:05 +02:00
parent dfeeeb5fdf
commit 800a544190
14 changed files with 28 additions and 35 deletions
+2 -1
View File
@@ -8,7 +8,7 @@ Order = impact. Font items + app.html preload intentionally skipped.
- [x] 2. Chart.js dynamic import in `FitnessChart.svelte` (drop 244 KB from non-stats fitness routes)
- [x] 3. Recipe API endpoints — drop `JSON.parse(JSON.stringify(...))` double-serialize (9 endpoints). Client-side shuffle / cache headers deferred (would require rethinking hero preload + hydration)
- [x] 4. Favorites page — drop unnecessary `all_brief` fetch (verified Search uses `favoritesOnly` so `allRecipes` was redundant)
- [ ] 5. Replace redundant `locals.auth()` with `locals.session` across recipe/calendar/fitness loaders
- [x] 5. Replace redundant `locals.auth()` with `locals.session` across recipe/calendar/fitness loaders (loaders only; actions + admin/edit/add pages skipped)
- [ ] 6. Stream fitness stats loader — return promises for slow panels
- [ ] 7. Overview endpoint — add `.select(...)` projection, cap timeseries window
- [ ] 8. Calendar payload trim — drop `name` from `yearDays`, pre-filter `feastDots` server-side
@@ -26,6 +26,7 @@ Order = impact. Font items + app.html preload intentionally skipped.
[x] on /fitness/stats/histoy/<part> for body measurement graphs, make the range reasonable. e.g., if we have 1 cm change, do not fill the entire y-height with 1 cm. Use reasonable padding for low ranges (i think we do something like htis already on the weight graph?)
[ ] Make the Period ended button a lot more prominent
[ ] swap heart emoji on recipe favorites to lucide icon
[ ] coop and migros cards on shopping list for scanning
## Refactor Recipe Search Component
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "homepage",
"version": "1.46.16",
"version": "1.46.17",
"private": true,
"type": "module",
"scripts": {
+4 -4
View File
@@ -8,7 +8,7 @@ import type { Session } from '@auth/sveltekit';
type BriefRecipeWithFavorite = BriefRecipeType & { isFavorite: boolean };
export async function getUserFavorites(fetch: typeof globalThis.fetch, locals: App.Locals, recipeLang = 'rezepte'): Promise<string[]> {
const session = await locals.auth();
const session = locals.session ?? await locals.auth();
if (!session?.user?.nickname) {
return [];
@@ -47,10 +47,10 @@ export async function loadRecipesWithFavorites(
recipeLoader: () => Promise<BriefRecipeType[]>,
recipeLang = 'rezepte'
): Promise<{ recipes: BriefRecipeWithFavorite[], session: Session | null }> {
const [recipes, userFavorites, session] = await Promise.all([
const session = locals.session ?? await locals.auth();
const [recipes, userFavorites] = await Promise.all([
recipeLoader(),
getUserFavorites(fetch, locals, recipeLang),
locals.auth()
getUserFavorites(fetch, locals, recipeLang)
]);
return {
@@ -36,7 +36,7 @@ export const load: PageServerLoad = async ({ params, url, locals, fetch }) => {
// Fetch angelus streak data for angelus/regina-caeli pages
if (angelusSlugs.has(params.prayer)) {
const session = await locals.auth();
const session = locals.session ?? await locals.auth();
if (session?.user?.nickname) {
try {
const res = await fetch('/api/glaube/angelus-streak');
@@ -43,7 +43,7 @@ function getMysteryForWeekday(date: Date, includeLuminous: boolean): string {
}
export const load: PageServerLoad = async ({ url, fetch, locals, params }) => {
const session = await locals.auth();
const session = locals.session ?? await locals.auth();
// Read toggle/mystery state from URL search params (for no-JS progressive enhancement)
const luminousParam = url.searchParams.get('luminous');
@@ -4,12 +4,11 @@ import { getUserFavorites, addFavoriteStatusToRecipes } from "$lib/server/favori
export const load: PageServerLoad = async ({ fetch, locals, params }) => {
const apiBase = `/api/${params.recipeLang}`;
const currentMonth = new Date().getMonth() + 1;
const session = locals.session ?? await locals.auth();
// Fetch all_brief, favorites, and session in parallel
const [res_all_brief, userFavorites, session] = await Promise.all([
const [res_all_brief, userFavorites] = await Promise.all([
fetch(`${apiBase}/items/all_brief`).then(r => r.json()),
getUserFavorites(fetch, locals, params.recipeLang),
locals.auth()
getUserFavorites(fetch, locals, params.recipeLang)
]);
const all_brief = addFavoriteStatusToRecipes(res_all_brief, userFavorites);
@@ -19,8 +19,7 @@ export const load: PageServerLoad = async ({ fetch, params, locals, url }) => {
const strippedName = stripHtmlTags(item.name);
const strippedDescription = stripHtmlTags(item.description);
// Get session for user info
const session = await locals.auth();
const session = locals.session ?? await locals.auth();
return {
item,
@@ -4,11 +4,11 @@ import { getUserFavorites, addFavoriteStatusToRecipes } from "$lib/server/favori
export const load: PageServerLoad = async ({ fetch, locals, params }) => {
const apiBase = `/api/${params.recipeLang}`;
const [res, allRes, userFavorites, session] = await Promise.all([
const session = locals.session ?? await locals.auth();
const [res, allRes, userFavorites] = await Promise.all([
fetch(`${apiBase}/items/category/${params.category}`),
fetch(`${apiBase}/items/all_brief`),
getUserFavorites(fetch, locals, params.recipeLang),
locals.auth()
getUserFavorites(fetch, locals, params.recipeLang)
]);
const [items, allRecipes] = await Promise.all([res.json(), allRes.json()]);
@@ -4,11 +4,11 @@ import { getUserFavorites, addFavoriteStatusToRecipes } from "$lib/server/favori
export const load: PageServerLoad = async ({ fetch, locals, params }) => {
const apiBase = `/api/${params.recipeLang}`;
const [item_season, icons, userFavorites, session] = await Promise.all([
const session = locals.session ?? await locals.auth();
const [item_season, icons, userFavorites] = await Promise.all([
fetch(`${apiBase}/items/icon/` + params.icon).then(r => r.json()),
fetch(`${apiBase}/items/icon`).then(r => r.json()),
getUserFavorites(fetch, locals, params.recipeLang),
locals.auth()
getUserFavorites(fetch, locals, params.recipeLang)
]);
return {
@@ -8,11 +8,8 @@ export const load: PageServerLoad = async ({ fetch, locals, params }) => {
const res_season = await fetch(`${apiBase}/items/in_season/` + current_month);
const item_season = await res_season.json();
// Get user favorites and session
const [userFavorites, session] = await Promise.all([
getUserFavorites(fetch, locals, params.recipeLang),
locals.auth()
]);
const session = locals.session ?? await locals.auth();
const userFavorites = await getUserFavorites(fetch, locals, params.recipeLang);
return {
season: addFavoriteStatusToRecipes(item_season, userFavorites),
@@ -7,11 +7,8 @@ export const load: PageServerLoad = async ({ fetch, locals, params }) => {
const res_season = await fetch(`${apiBase}/items/in_season/` + params.month);
const item_season = await res_season.json();
// Get user favorites and session
const [userFavorites, session] = await Promise.all([
getUserFavorites(fetch, locals, params.recipeLang),
locals.auth()
]);
const session = locals.session ?? await locals.auth();
const userFavorites = await getUserFavorites(fetch, locals, params.recipeLang);
return {
month: params.month,
@@ -4,11 +4,11 @@ import { getUserFavorites, addFavoriteStatusToRecipes } from "$lib/server/favori
export const load: PageServerLoad = async ({ fetch, locals, params }) => {
const apiBase = `/api/${params.recipeLang}`;
const [res_tag, allRes, userFavorites, session] = await Promise.all([
const session = locals.session ?? await locals.auth();
const [res_tag, allRes, userFavorites] = await Promise.all([
fetch(`${apiBase}/items/tag/${params.tag}`),
fetch(`${apiBase}/items/all_brief`),
getUserFavorites(fetch, locals, params.recipeLang),
locals.auth()
getUserFavorites(fetch, locals, params.recipeLang)
]);
const [items_tag, allRecipes] = await Promise.all([res_tag.json(), allRes.json()]);
@@ -4,7 +4,7 @@ import { ToTryRecipe } from '$models/ToTryRecipe';
import { dbConnect } from '$utils/db';
export const load: PageServerLoad = async ({ locals, params }) => {
const session = await locals.auth();
const session = locals.session ?? await locals.auth();
if (!session?.user) {
const callbackUrl = encodeURIComponent(`/${params.recipeLang}/to-try`);
@@ -1,7 +1,7 @@
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ fetch, locals }) => {
const session = await locals.auth();
const session = locals.session ?? await locals.auth();
const [res, goalRes, heatmapRes, nutritionRes, latestRes, periodRes, sharedRes] = await Promise.all([
fetch('/api/fitness/stats/overview'),
fetch('/api/fitness/goal'),