Browse Source

⚡ perf(playground): optimize config loading and saving to reduce console spam

- Cache initial config using useRef to prevent repeated loadConfig() calls
- Fix useEffect dependencies to only trigger on actual config changes
- Modify debouncedSaveConfig dependency from function reference to actual config values
- Update handleConfigReset to use DEFAULT_CONFIG directly instead of reloading
- Prevent excessive console logging during chat interactions and frequent re-renders

This resolves the issue where console was flooded with:
"配置已从本地存储加载" and "配置已保存到本地存储" messages,
especially during active chat sessions where logs appeared every second.

Fixes: Frequent config load/save operations causing performance issues
Apple\Apple 9 months ago
parent
commit
b548c6c827
3 changed files with 26 additions and 21 deletions
  1. 1 1
      web/src/App.js
  2. 11 7
      web/src/hooks/usePlaygroundState.js
  3. 14 13
      web/src/pages/Playground/index.js

+ 1 - 1
web/src/App.js

@@ -22,7 +22,7 @@ import { Layout } from '@douyinfe/semi-ui';
 import Midjourney from './pages/Midjourney';
 import Pricing from './pages/Pricing/index.js';
 import Task from './pages/Task/index.js';
-import Playground from './pages/Playground/Playground.js';
+import Playground from './pages/Playground/index.js';
 import OAuth2Callback from './components/OAuth2Callback.js';
 import PersonalSetting from './components/PersonalSetting.js';
 import Setup from './pages/Setup/index.js';

+ 11 - 7
web/src/hooks/usePlaygroundState.js

@@ -1,9 +1,14 @@
-import { useState, useCallback, useRef } from 'react';
+import { useState, useCallback, useRef, useEffect } from 'react';
 import { DEFAULT_MESSAGES, DEFAULT_CONFIG, DEBUG_TABS } from '../utils/constants';
 import { loadConfig, saveConfig } from '../components/playground/configStorage';
 
 export const usePlaygroundState = () => {
-  const savedConfig = loadConfig();
+  // 使用 ref 缓存初始配置,只加载一次
+  const initialConfigRef = useRef(null);
+  if (!initialConfigRef.current) {
+    initialConfigRef.current = loadConfig();
+  }
+  const savedConfig = initialConfigRef.current;
 
   // 基础配置状态
   const [inputs, setInputs] = useState(savedConfig.inputs || DEFAULT_CONFIG.inputs);
@@ -92,11 +97,10 @@ export const usePlaygroundState = () => {
   }, []);
 
   const handleConfigReset = useCallback(() => {
-    const defaultConfig = loadConfig();
-    setInputs(defaultConfig.inputs);
-    setParameterEnabled(defaultConfig.parameterEnabled);
-    setSystemPrompt(defaultConfig.systemPrompt);
-    setShowDebugPanel(defaultConfig.showDebugPanel);
+    setInputs(DEFAULT_CONFIG.inputs);
+    setParameterEnabled(DEFAULT_CONFIG.parameterEnabled);
+    setSystemPrompt(DEFAULT_CONFIG.systemPrompt);
+    setShowDebugPanel(DEFAULT_CONFIG.showDebugPanel);
   }, []);
 
   return {

+ 14 - 13
web/src/pages/Playground/Playground.js → web/src/pages/Playground/index.js

@@ -10,35 +10,35 @@ import { StyleContext } from '../../context/Style/index.js';
 // Utils and hooks
 import { API, showError, getLogo, isMobile } from '../../helpers/index.js';
 import { stringToColor } from '../../helpers/render.js';
-import { usePlaygroundState } from '../../hooks/usePlaygroundState';
-import { useMessageActions } from '../../hooks/useMessageActions';
-import { useApiRequest } from '../../hooks/useApiRequest';
+import { usePlaygroundState } from '../../hooks/usePlaygroundState.js';
+import { useMessageActions } from '../../hooks/useMessageActions.js';
+import { useApiRequest } from '../../hooks/useApiRequest.js';
 
 // Constants and utils
 import {
   DEFAULT_MESSAGES,
   MESSAGE_ROLES,
   API_ENDPOINTS
-} from '../../utils/constants';
+} from '../../utils/constants.js';
 import {
   buildMessageContent,
   createMessage,
   createLoadingAssistantMessage,
   getTextContent
-} from '../../utils/messageUtils';
+} from '../../utils/messageUtils.js';
 import {
   buildApiPayload,
   processModelsData,
   processGroupsData
-} from '../../utils/apiUtils';
+} from '../../utils/apiUtils.js';
 
 // Components
-import SettingsPanel from '../../components/playground/SettingsPanel';
-import ChatArea from '../../components/playground/ChatArea';
-import DebugPanel from '../../components/playground/DebugPanel';
-import MessageContent from '../../components/playground/MessageContent';
-import MessageActions from '../../components/playground/MessageActions';
-import FloatingButtons from '../../components/playground/FloatingButtons';
+import SettingsPanel from '../../components/playground/SettingsPanel.js';
+import ChatArea from '../../components/playground/ChatArea.js';
+import DebugPanel from '../../components/playground/DebugPanel.js';
+import MessageContent from '../../components/playground/MessageContent.js';
+import MessageActions from '../../components/playground/MessageActions.js';
+import FloatingButtons from '../../components/playground/FloatingButtons.js';
 
 // 生成头像
 const generateAvatarDataUrl = (username) => {
@@ -413,9 +413,10 @@ const Playground = () => {
     }));
   }, [constructPreviewPayload, setPreviewPayload, setDebugData]);
 
+  // 监听配置变化并自动保存
   useEffect(() => {
     debouncedSaveConfig();
-  }, [debouncedSaveConfig]);
+  }, [inputs, parameterEnabled, systemPrompt, showDebugPanel]);
 
   return (
     <div className="h-full bg-gray-50">