Merge pull request #57 from jhbruhn/fix/memoize-pattern-canvas-calculations

fix: Add memoization to PatternCanvas expensive computations
This commit is contained in:
Jan-Henrik Bruhn 2025-12-27 17:02:11 +01:00 committed by GitHub
commit 957a3f07b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,4 +1,4 @@
import { useRef } from "react"; import { useRef, useMemo } from "react";
import { useShallow } from "zustand/react/shallow"; import { useShallow } from "zustand/react/shallow";
import { import {
useMachineStore, useMachineStore,
@ -109,6 +109,26 @@ export function PatternCanvas() {
? "text-tertiary-600 dark:text-tertiary-400" ? "text-tertiary-600 dark:text-tertiary-400"
: "text-gray-600 dark:text-gray-400"; : "text-gray-600 dark:text-gray-400";
// Memoize the display pattern to avoid recalculation
const displayPattern = useMemo(
() => uploadedPesData || pesData,
[uploadedPesData, pesData],
);
// Memoize pattern dimensions calculation
const patternDimensions = useMemo(() => {
if (!displayPattern) return null;
const width = (
(displayPattern.bounds.maxX - displayPattern.bounds.minX) /
10
).toFixed(1);
const height = (
(displayPattern.bounds.maxY - displayPattern.bounds.minY) /
10
).toFixed(1);
return `${width} × ${height} mm`;
}, [displayPattern]);
return ( return (
<Card <Card
className={`p-0 gap-0 lg:h-full flex flex-col border-l-4 ${borderColor}`} className={`p-0 gap-0 lg:h-full flex flex-col border-l-4 ${borderColor}`}
@ -120,25 +140,7 @@ export function PatternCanvas() {
<CardTitle className="text-sm">Pattern Preview</CardTitle> <CardTitle className="text-sm">Pattern Preview</CardTitle>
{hasPattern ? ( {hasPattern ? (
<CardDescription className="text-xs"> <CardDescription className="text-xs">
{(() => { {patternDimensions}
const displayPattern = uploadedPesData || pesData;
return displayPattern ? (
<>
{(
(displayPattern.bounds.maxX -
displayPattern.bounds.minX) /
10
).toFixed(1)}{" "}
×{" "}
{(
(displayPattern.bounds.maxY -
displayPattern.bounds.minY) /
10
).toFixed(1)}{" "}
mm
</>
) : null;
})()}
</CardDescription> </CardDescription>
) : ( ) : (
<CardDescription className="text-xs"> <CardDescription className="text-xs">
@ -182,11 +184,11 @@ export function PatternCanvas() {
> >
{/* Background layer: grid, origin, hoop */} {/* Background layer: grid, origin, hoop */}
<Layer> <Layer>
{hasPattern && ( {displayPattern && (
<> <>
<Grid <Grid
gridSize={100} gridSize={100}
bounds={(uploadedPesData || pesData)!.bounds} bounds={displayPattern.bounds}
machineInfo={machineInfo} machineInfo={machineInfo}
/> />
<Origin /> <Origin />
@ -241,11 +243,7 @@ export function PatternCanvas() {
)} )}
{/* Pattern info overlays */} {/* Pattern info overlays */}
{hasPattern && {displayPattern && (
(() => {
const displayPattern = uploadedPesData || pesData;
return (
displayPattern && (
<> <>
<ThreadLegend colors={displayPattern.uniqueColors} /> <ThreadLegend colors={displayPattern.uniqueColors} />
@ -274,9 +272,7 @@ export function PatternCanvas() {
} }
/> />
</> </>
) )}
);
})()}
</div> </div>
</CardContent> </CardContent>
</Card> </Card>