perf: add Server-Timing, split fitness bundle, tighten DB queries

- Add `timing` handle in hooks.server.ts emitting Server-Timing headers
  and expose `locals.timing.mark/measure` for per-load instrumentation.
- Drop dead `getEnrichedExerciseById` fallback in fitness detail page —
  server load already 404s via errorWithVerse, so the client no longer
  pulls exercisedb-raw.json (~760KB) into the detail bundle.
- Add `{ createdBy: 1, nextExecutionDate: -1 }` index on RecurringPayment
  for user-scoped list queries.
- Narrow populate projections in cospend/debts (title/date/category on
  userSplits, _id only on allRelatedSplits) to cut payload + hydration.
- Parallelize today's sessions + WorkoutSchedule lookup in the nutrition
  page load via Promise.all; add `.lean()` + `.select('templateId')` to
  the lastScheduled query.
This commit is contained in:
2026-04-21 07:36:55 +02:00
parent 58b3d4b478
commit 9093e0fe51
7 changed files with 44 additions and 13 deletions
+2 -2
View File
@@ -31,7 +31,7 @@ export const GET: RequestHandler = async ({ locals }) => {
try {
// Get all splits for the current user
const userSplits = await PaymentSplit.find({ username: currentUser })
.populate('paymentId')
.populate('paymentId', 'title date category _id')
.lean();
// Get all other users who have splits with payments involving the current user
@@ -40,7 +40,7 @@ export const GET: RequestHandler = async ({ locals }) => {
paymentId: { $in: paymentIds } as any,
username: { $ne: currentUser }
})
.populate('paymentId')
.populate('paymentId', '_id')
.lean();
// Group debts by user
@@ -1,6 +1,5 @@
<script>
import { page } from '$app/stores';
import { getEnrichedExerciseById } from '$lib/data/exercisedb';
/** @param {string | undefined | null} type @param {'en'|'de'} lang */
function exerciseTypeInfo(type, lang) {
@@ -20,7 +19,6 @@
return null;
}
}
import { localizeExercise, translateTerm } from '$lib/data/exercises';
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
import { ChevronRight } from '@lucide/svelte';
@@ -54,7 +52,7 @@
let activeTab = $state('about');
const exercise = $derived(data.exercise ?? getEnrichedExerciseById($page.params.id, lang));
const exercise = $derived(data.exercise);
const typeInfo = $derived(exerciseTypeInfo(exercise?.exerciseType, lang));
const similar = $derived(data.similar ?? []);
const history = $derived(data.history?.history ?? []);
@@ -19,10 +19,13 @@ export const load: PageServerLoad = async ({ fetch, params, locals }) => {
try {
const user = await requireAuth(locals);
await dbConnect();
const sessions = await WorkoutSession.find({
createdBy: user.nickname,
startTime: { $gte: dayStart, $lte: dayEnd }
}).select('kcalEstimate').lean();
const [sessions, schedule] = await Promise.all([
WorkoutSession.find({
createdBy: user.nickname,
startTime: { $gte: dayStart, $lte: dayEnd }
}).select('kcalEstimate').lean(),
WorkoutSchedule.findOne({ userId: user.nickname }).lean()
]);
let kcal = 0;
for (const s of sessions) {
if (s.kcalEstimate?.kcal) kcal += s.kcalEstimate.kcal;
@@ -31,12 +34,11 @@ export const load: PageServerLoad = async ({ fetch, params, locals }) => {
// If no exercise done today, project kcal from the next scheduled template
let projected = null;
if (kcal === 0) {
const schedule = await WorkoutSchedule.findOne({ userId: user.nickname });
if (schedule?.templateOrder?.length) {
const lastScheduled = await WorkoutSession.findOne({
createdBy: user.nickname,
templateId: { $in: schedule.templateOrder }
}).sort({ startTime: -1 });
}).sort({ startTime: -1 }).select('templateId').lean();
let nextId;
if (!lastScheduled?.templateId) {