perf: skip processing when properties are at neutral values

Add getEffectiveConfig function that only considers values affecting output.
Toggling a property on at its neutral value (e.g., gamma at 1.0) no longer
triggers a reprocess since the output would be identical.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 07:09:56 -04:00
parent a1b653efb7
commit dbb896e2b7

View File

@@ -18,16 +18,86 @@
let previewDataUrl = $state<string | null>(null); let previewDataUrl = $state<string | null>(null);
let isProcessing = $state(false); let isProcessing = $state(false);
let debounceTimer: ReturnType<typeof setTimeout> | null = null; let debounceTimer: ReturnType<typeof setTimeout> | null = null;
let initialEffectiveConfig = $state<string | null>(null);
const isManualCrop = $derived(config.crop.enabled && config.crop.mode === 'manual'); const isManualCrop = $derived(config.crop.enabled && config.crop.mode === 'manual');
const targetAspect = $derived(device.width / device.height); const targetAspect = $derived(device.width / device.height);
// Build a string representing only config values that affect output
// Properties at neutral values are equivalent to being disabled
function getEffectiveConfig(cfg: PipelineConfig): string {
const effective: Record<string, unknown> = {};
// Crop: only matters if enabled
if (cfg.crop.enabled) {
effective.crop = { mode: cfg.crop.mode, region: cfg.crop.region };
}
// Resize: only matters if enabled
if (cfg.resize.enabled) {
effective.resize = true;
}
// Brightness: 0 is neutral
if (cfg.brightness.enabled && cfg.brightness.value !== 0) {
effective.brightness = cfg.brightness.value;
}
// Contrast: 0 is neutral
if (cfg.contrast.enabled && cfg.contrast.value !== 0) {
effective.contrast = cfg.contrast.value;
}
// Gamma: 1.0 is neutral
if (cfg.gamma.enabled && cfg.gamma.value !== 1.0) {
effective.gamma = cfg.gamma.value;
}
// Greyscale: only matters if enabled
if (cfg.greyscale.enabled) {
effective.greyscale = true;
}
// Sharpen: 0 amount is neutral
if (cfg.sharpen.enabled && cfg.sharpen.amount > 0) {
effective.sharpen = cfg.sharpen.amount;
}
// Auto-levels: only matters if enabled
if (cfg.autoLevels.enabled) {
effective.autoLevels = cfg.autoLevels.clipPercent;
}
// Dither: only matters if enabled
if (cfg.dither.enabled) {
effective.dither = cfg.dither.algorithm;
}
// Quantize: only matters if enabled
if (cfg.quantize.enabled) {
effective.quantize = cfg.quantize.levels;
}
return JSON.stringify(effective);
}
// Capture initial effective config on mount
$effect(() => {
if (initialEffectiveConfig === null) {
initialEffectiveConfig = getEffectiveConfig(config);
}
});
// Track config changes and trigger debounced processing // Track config changes and trigger debounced processing
$effect(() => { $effect(() => {
// Access config to create dependency (but skip processing in manual crop mode without region) const effectiveConfig = getEffectiveConfig(config);
const configStr = JSON.stringify(config);
// Don't process if in manual crop mode - wait for region to be set // Skip if effective config hasn't changed (prevents unnecessary reprocessing)
if (effectiveConfig === initialEffectiveConfig) {
return;
}
// Don't process if in manual crop mode without region
if (isManualCrop && !config.crop.region) { if (isManualCrop && !config.crop.region) {
return; return;
} }