mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
perf(dashboard): memoise the band math and the module-list parse
The dashboard recomputed the client band fallback on every render even when the server snapshot supplied bands, and the module-list-prefs hook reparsed its stored JSON into a fresh object each render, defeating downstream memoisation. Wrap both in useMemo keyed on their real inputs.
This commit is contained in:
1 parent
9eed8d9cfe
commit
3ec9aca798
2 files changed
+20
-7
No files matched your search
+14
-5
@@ -532,11 +532,20 @@ export default function DashboardPage() {
|
||||
// — it is pure + cheap — so a still-loading snapshot frame keeps real
|
||||
// bands rather than blank charts; `serverBands ?? clientBands` then
|
||||
// prefers the authoritative server numbers the moment they arrive.
|
||||
const clientBands = buildDashboardBands({
|
||||
dateOfBirth: user?.dateOfBirth ? new Date(user.dateOfBirth) : null,
|
||||
gender: (user?.gender as "MALE" | "FEMALE" | null | undefined) ?? null,
|
||||
heightCm: user?.heightCm ?? null,
|
||||
});
|
||||
// Inputs only change with profile facts, so memoise the band math — it
|
||||
// ran on every dashboard render (and got discarded by `serverBands ??`
|
||||
// in the snapshot steady state) before this. Keyed on the `user` object
|
||||
// identity so the React Compiler can preserve the memo (a narrower
|
||||
// property list trips `preserve-manual-memoization`).
|
||||
const clientBands = useMemo(
|
||||
() =>
|
||||
buildDashboardBands({
|
||||
dateOfBirth: user?.dateOfBirth ? new Date(user.dateOfBirth) : null,
|
||||
gender: (user?.gender as "MALE" | "FEMALE" | null | undefined) ?? null,
|
||||
heightCm: user?.heightCm ?? null,
|
||||
}),
|
||||
[user],
|
||||
);
|
||||
const bands = serverBands ?? clientBands;
|
||||
const bpTargets = bands.bpTargets;
|
||||
const weightRange = bands.weightRange;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* block (the server default order is preserved for the tail).
|
||||
*/
|
||||
|
||||
import { useCallback, useSyncExternalStore } from "react";
|
||||
import { useCallback, useMemo, useSyncExternalStore } from "react";
|
||||
|
||||
export const MODULE_LIST_VIEWS = ["cards", "list"] as const;
|
||||
export type ModuleListView = (typeof MODULE_LIST_VIEWS)[number];
|
||||
@@ -150,7 +150,11 @@ export function useModuleListPrefs(module: ModuleListKey): {
|
||||
}, [key]);
|
||||
|
||||
const raw = useSyncExternalStore(subscribe, getSnapshot, () => null);
|
||||
const prefs = parseModuleListPrefs(raw);
|
||||
// `useSyncExternalStore` returns a stable `raw` string when storage hasn't
|
||||
// changed, so keying the parse on it gives downstream `applyOrder`
|
||||
// memoisation a stable `prefs` reference instead of a fresh object + a
|
||||
// JSON.parse on every render.
|
||||
const prefs = useMemo(() => parseModuleListPrefs(raw), [raw]);
|
||||
|
||||
const write = useCallback(
|
||||
(next: ModuleListPrefs) => {
|
||||
|
||||
Reference in new issue
Block a user