@@ -114,7 +119,7 @@ export function ProfilingSettings({ max="1000" step="10" value={localConfig.maxSnapshots} - onChange={(e) => updateLocalConfig({ maxSnapshots: parseInt(e.target.value) })} + onChange={(e) => { const v = parseInt(e.target.value); if (!isNaN(v)) updateLocalConfig({ maxSnapshots: v }); }} className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
@@ -233,12 +238,12 @@ export function ProfilingSettings({
min="10"
max="1000"
value={Math.round(localConfig.memoryBudget.total / 1024 / 1024)}
- onChange={(e) => updateLocalConfig({
+ onChange={(e) => { const v = parseInt(e.target.value); if (!isNaN(v)) updateLocalConfig({
memoryBudget: {
...localConfig.memoryBudget!,
- total: parseInt(e.target.value) * 1024 * 1024
+ total: v * 1024 * 1024
}
- })}
+ }); }}
className="w-full px-3 py-2 pr-12 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
@@ -257,12 +262,12 @@ export function ProfilingSettings({
min="10"
max="1000"
value={Math.round(localConfig.memoryBudget.warning / 1024 / 1024)}
- onChange={(e) => updateLocalConfig({
+ onChange={(e) => { const v = parseInt(e.target.value); if (!isNaN(v)) updateLocalConfig({
memoryBudget: {
...localConfig.memoryBudget!,
- warning: parseInt(e.target.value) * 1024 * 1024
+ warning: v * 1024 * 1024
}
- })}
+ }); }}
className="w-full px-3 py-2 pr-12 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
@@ -281,12 +286,12 @@ export function ProfilingSettings({
min="10"
max="1000"
value={Math.round(localConfig.memoryBudget.critical / 1024 / 1024)}
- onChange={(e) => updateLocalConfig({
+ onChange={(e) => { const v = parseInt(e.target.value); if (!isNaN(v)) updateLocalConfig({
memoryBudget: {
...localConfig.memoryBudget!,
- critical: parseInt(e.target.value) * 1024 * 1024
+ critical: v * 1024 * 1024
}
- })}
+ }); }}
className="w-full px-3 py-2 pr-12 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
diff --git a/plugins/render-waste-detector/src/components/PluginPanel.tsx b/plugins/render-waste-detector/src/components/PluginPanel.tsx
index b50b5d1..8d0339a 100644
--- a/plugins/render-waste-detector/src/components/PluginPanel.tsx
+++ b/plugins/render-waste-detector/src/components/PluginPanel.tsx
@@ -1,4 +1,4 @@
-import React, { useMemo } from "react";
+import React, { useEffect, useMemo } from "react";
import { useSyncExternalStore } from "use-sync-external-store/shim";
import {
Activity,
@@ -52,18 +52,17 @@ function PluginPanelInner({
children,
}: RenderWasteDetectorPanelProps) {
// Create or get event client
- const eventClient = (() => {
- const client =
- getRenderWasteDetectorDevToolsClient() ||
- createRenderWasteDetectorDevToolsClient();
+ const eventClient = useMemo(() => {
+ return getRenderWasteDetectorDevToolsClient() || createRenderWasteDetectorDevToolsClient();
+ }, []);
- // Apply default settings if provided
+ // Apply default settings on mount only
+ useEffect(() => {
if (defaultSettings) {
- client.updateSettings(defaultSettings);
+ eventClient.updateSettings(defaultSettings);
}
-
- return client;
- })();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
// Subscribe to state changes
const state = useSyncExternalStore
@@ -162,12 +157,7 @@ export function SettingsTab({
max="3600000"
step="1000"
value={settings.maxRecordingTime}
- onChange={(e) =>
- handleSettingChange(
- "maxRecordingTime",
- parseInt(e.target.value),
- )
- }
+ onChange={(e) => { const v = parseInt(e.target.value); if (!isNaN(v)) handleSettingChange("maxRecordingTime", v); }}
/>
@@ -185,7 +175,7 @@ export function SettingsTab({
step="100"
value={settings.maxEvents}
onChange={(e) =>
- handleSettingChange("maxEvents", parseInt(e.target.value))
+ { const v = parseInt(e.target.value); if (!isNaN(v)) handleSettingChange("maxEvents", v); }
}
/>
@@ -204,7 +194,7 @@ export function SettingsTab({
step="10"
value={settings.debounceMs}
onChange={(e) =>
- handleSettingChange("debounceMs", parseInt(e.target.value))
+ { const v = parseInt(e.target.value); if (!isNaN(v)) handleSettingChange("debounceMs", v); }
}
/>
diff --git a/plugins/render-waste-detector/src/components/tabs/TimelineTab.tsx b/plugins/render-waste-detector/src/components/tabs/TimelineTab.tsx
index b00fdb2..c6fa9b7 100644
--- a/plugins/render-waste-detector/src/components/tabs/TimelineTab.tsx
+++ b/plugins/render-waste-detector/src/components/tabs/TimelineTab.tsx
@@ -76,7 +76,7 @@ export function TimelineTab({
key={event.id}
className={`timeline-event ${event.reason}`}
style={{
- left: `${(event.timestamp - renderEvents[0]?.timestamp || 0) / 10}px`,
+ left: `${(event.timestamp - (renderEvents[0]?.timestamp ?? 0)) / 10}px`,
width: `${Math.max(2, event.duration / 2)}px`,
}}
title={`${event.componentName}: ${event.reason} (${event.duration.toFixed(1)}ms)`}