mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
perf(dashboard): load the quick-entry forms when a sheet opens
The dashboard and the bottom bar's capture picker imported all five quick-entry forms eagerly, so every authenticated paint carried them for sheets most visits never open. One module now wraps them in next/dynamic (client-only, a skeleton holding the sheet body while the chunk loads) and both callers use it. The discard guard stays static. The picker tests mock the one module instead of five.
This commit is contained in:
1 parent
bcbfd87ae9
commit
65b2f75421
5 files changed
+88
-22
No files matched your search
@@ -0,0 +1,68 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* The quick-entry forms, loaded when a sheet first opens rather than with the
|
||||
* page. The dashboard and the bottom bar's capture picker are on nearly every
|
||||
* authenticated paint, and both used to import all five forms eagerly (each
|
||||
* with react-hook-form, zod, its pickers and its own queries) for sheets most
|
||||
* visits never open.
|
||||
*
|
||||
* Client-only (`ssr: false`): every sheet is closed on the server render. The
|
||||
* options are inline object literals because the bundler requires them so.
|
||||
* The placeholder holds the sheet body's height while the chunk arrives so the
|
||||
* sheet does not grow under the finger. Same `next/dynamic` arrangement as
|
||||
* the Coach drawer mount.
|
||||
*/
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
function SheetBodySkeleton() {
|
||||
return (
|
||||
<div className="space-y-4" data-slot="quick-entry-form-loading">
|
||||
<Skeleton className="h-10 w-full" />
|
||||
<Skeleton className="h-10 w-full" />
|
||||
<Skeleton className="h-10 w-2/3" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const MeasurementForm = dynamic(
|
||||
() =>
|
||||
import("@/components/measurements/measurement-form").then((m) => ({
|
||||
default: m.MeasurementForm,
|
||||
})),
|
||||
{ ssr: false, loading: SheetBodySkeleton },
|
||||
);
|
||||
|
||||
export const MoodForm = dynamic(
|
||||
() =>
|
||||
import("@/components/mood/mood-form").then((m) => ({
|
||||
default: m.MoodForm,
|
||||
})),
|
||||
{ ssr: false, loading: SheetBodySkeleton },
|
||||
);
|
||||
|
||||
export const MedicationIntakeQuickAdd = dynamic(
|
||||
() =>
|
||||
import("@/components/dashboard/medication-intake-quick-add").then((m) => ({
|
||||
default: m.MedicationIntakeQuickAdd,
|
||||
})),
|
||||
{ ssr: false, loading: SheetBodySkeleton },
|
||||
);
|
||||
|
||||
export const ManualWorkoutForm = dynamic(
|
||||
() =>
|
||||
import("@/components/workouts/manual-workout-form").then((m) => ({
|
||||
default: m.ManualWorkoutForm,
|
||||
})),
|
||||
{ ssr: false, loading: SheetBodySkeleton },
|
||||
);
|
||||
|
||||
export const SymptomEntryForm = dynamic(
|
||||
() =>
|
||||
import("@/components/symptoms/symptom-entry-form").then((m) => ({
|
||||
default: m.SymptomEntryForm,
|
||||
})),
|
||||
{ ssr: false, loading: SheetBodySkeleton },
|
||||
);
|
||||
@@ -11,6 +11,13 @@
|
||||
*/
|
||||
import { useState } from "react";
|
||||
import { ResponsiveSheet } from "@/components/ui/responsive-sheet";
|
||||
import {
|
||||
ManualWorkoutForm,
|
||||
MeasurementForm,
|
||||
MedicationIntakeQuickAdd,
|
||||
MoodForm,
|
||||
SymptomEntryForm,
|
||||
} from "@/components/dashboard/quick-entry-forms.lazy";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
@@ -21,11 +28,6 @@ import {
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { MeasurementForm } from "@/components/measurements/measurement-form";
|
||||
import { MoodForm } from "@/components/mood/mood-form";
|
||||
import { MedicationIntakeQuickAdd } from "@/components/dashboard/medication-intake-quick-add";
|
||||
import { ManualWorkoutForm } from "@/components/workouts/manual-workout-form";
|
||||
import { SymptomEntryForm } from "@/components/symptoms/symptom-entry-form";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
import {
|
||||
useRecordCapabilities,
|
||||
|
||||
@@ -82,14 +82,12 @@ vi.mock("@/components/ui/alert-dialog", () => ({
|
||||
AlertDialogTitle: markedComponent("AlertDialogTitle"),
|
||||
}));
|
||||
|
||||
vi.mock("@/components/measurements/measurement-form", () => ({
|
||||
vi.mock("@/components/dashboard/quick-entry-forms.lazy", () => ({
|
||||
MeasurementForm: markedComponent("MeasurementForm"),
|
||||
}));
|
||||
vi.mock("@/components/mood/mood-form", () => ({
|
||||
MoodForm: markedComponent("MoodForm"),
|
||||
}));
|
||||
vi.mock("@/components/dashboard/medication-intake-quick-add", () => ({
|
||||
MedicationIntakeQuickAdd: markedComponent("MedicationIntakeQuickAdd"),
|
||||
ManualWorkoutForm: markedComponent("ManualWorkoutForm"),
|
||||
SymptomEntryForm: markedComponent("SymptomEntryForm"),
|
||||
}));
|
||||
|
||||
import { CapturePicker } from "../capture-picker";
|
||||
|
||||
@@ -35,16 +35,12 @@ vi.mock("@/components/ui/responsive-sheet", () => ({
|
||||
}) => (open ? <section>{children}</section> : null),
|
||||
}));
|
||||
|
||||
vi.mock("@/components/measurements/measurement-form", () => ({
|
||||
vi.mock("@/components/dashboard/quick-entry-forms.lazy", () => ({
|
||||
MeasurementForm: () => <div data-testid="measurement-form" />,
|
||||
}));
|
||||
|
||||
vi.mock("@/components/mood/mood-form", () => ({
|
||||
MoodForm: () => <div data-testid="mood-form" />,
|
||||
}));
|
||||
|
||||
vi.mock("@/components/dashboard/medication-intake-quick-add", () => ({
|
||||
MedicationIntakeQuickAdd: () => <div data-testid="medication-form" />,
|
||||
ManualWorkoutForm: () => <div data-testid="workout-form" />,
|
||||
SymptomEntryForm: () => <div data-testid="symptom-form" />,
|
||||
}));
|
||||
|
||||
import { CapturePicker } from "../capture-picker";
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
import { useState } from "react";
|
||||
import { Activity, Footprints, Pill, Stethoscope, Waves } from "lucide-react";
|
||||
|
||||
import { MeasurementForm } from "@/components/measurements/measurement-form";
|
||||
import { MoodForm } from "@/components/mood/mood-form";
|
||||
import { MedicationIntakeQuickAdd } from "@/components/dashboard/medication-intake-quick-add";
|
||||
import { ManualWorkoutForm } from "@/components/workouts/manual-workout-form";
|
||||
import { SymptomEntryForm } from "@/components/symptoms/symptom-entry-form";
|
||||
import { ResponsiveSheet } from "@/components/ui/responsive-sheet";
|
||||
import {
|
||||
ManualWorkoutForm,
|
||||
MeasurementForm,
|
||||
MedicationIntakeQuickAdd,
|
||||
MoodForm,
|
||||
SymptomEntryForm,
|
||||
} from "@/components/dashboard/quick-entry-forms.lazy";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
|
||||
Reference in new issue
Block a user