// Core dependencies import React, { Suspense, useEffect, memo, useMemo, useCallback } from 'react'; import { RouterProvider } from 'react-router-dom'; import i18next from 'i18next'; import { ensureTranslationsLoaded } from './i18n'; // Components import ThemeWrapper from './features/theme/ThemeWrapper'; // Routes import router from './app/routes'; // Hooks & Utils import { useAppSelector } from './hooks/useAppSelector'; import { initMixpanel } from './utils/mixpanelInit'; import { initializeCsrfToken } from './api/api-client'; // Types & Constants import { Language } from './features/i18n/localesSlice'; import logger from './utils/errorLogger'; import { SuspenseFallback } from './components/suspense-fallback/suspense-fallback'; /** * Main App Component - Performance Optimized * * Performance optimizations applied: * 1. React.memo() - Prevents unnecessary re-renders * 2. useMemo() - Memoizes expensive computations * 3. useCallback() - Memoizes event handlers * 4. Lazy loading - All route components loaded on demand * 5. Suspense boundaries - Better loading states * 6. Optimized guard components with memoization */ const App: React.FC = memo(() => { const themeMode = useAppSelector(state => state.themeReducer.mode); const language = useAppSelector(state => state.localesReducer.lng); // Memoize mixpanel initialization to prevent re-initialization const mixpanelToken = useMemo(() => import.meta.env.VITE_MIXPANEL_TOKEN as string, []); useEffect(() => { initMixpanel(mixpanelToken); }, [mixpanelToken]); // Memoize language change handler const handleLanguageChange = useCallback((lng: string) => { i18next.changeLanguage(lng, err => { if (err) return logger.error('Error changing language', err); }); }, []); useEffect(() => { document.documentElement.setAttribute('data-theme', themeMode); }, [themeMode]); useEffect(() => { handleLanguageChange(language || Language.EN); }, [language, handleLanguageChange]); // Initialize CSRF token and translations on app startup useEffect(() => { let isMounted = true; const initializeApp = async () => { try { // Initialize CSRF token await initializeCsrfToken(); // Preload essential translations await ensureTranslationsLoaded(); } catch (error) { if (isMounted) { logger.error('Failed to initialize app:', error); } } }; initializeApp(); return () => { isMounted = false; }; }, []); return ( }> ); }); App.displayName = 'App'; export default App;