refactor: remove unnecessary useMemo calls across components
Replace over-cached simple computations with direct expressions: - popup/App.tsx: getEntryPointType() and routerConfig (values are stable) - Dashboard/index.tsx: visibleSet, visibleFeatures, recentFeatures (Set creation + array filter/map are cheaper than useMemo overhead) - useTextStatistics.ts: getTextStats(text) (simple string processing) - ThemeModeProvider.tsx: contextValue object (setMode is stable via useCallback) -39 lines, +28 lines (net -11 lines) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3,25 +3,21 @@ import TopBar from '@/components/TopBar';
|
|||||||
import RouterContainer from '@/components/RouterContainer';
|
import RouterContainer from '@/components/RouterContainer';
|
||||||
import ErrorBoundary from '@/components/ErrorBoundary';
|
import ErrorBoundary from '@/components/ErrorBoundary';
|
||||||
import { getEntryPointType } from '@/config/features';
|
import { getEntryPointType } from '@/config/features';
|
||||||
import { useMemo } from 'react';
|
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const entryType = useMemo(() => getEntryPointType(), []);
|
const entryType = getEntryPointType();
|
||||||
|
|
||||||
const routerConfig = useMemo(() => {
|
const routerConfig =
|
||||||
if (entryType === 'tab') {
|
entryType === 'tab'
|
||||||
return {
|
? {
|
||||||
syncKey: 'app/tabRoute' as const,
|
syncKey: 'app/tabRoute' as const,
|
||||||
visiblePagesKey: 'app/tabVisiblePages' as const,
|
visiblePagesKey: 'app/tabVisiblePages' as const,
|
||||||
pageOrderKey: 'app/tabPageOrder' as const,
|
pageOrderKey: 'app/tabPageOrder' as const,
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return {
|
: {
|
||||||
syncKey: 'app/popupRoute' as const,
|
syncKey: 'app/popupRoute' as const,
|
||||||
visiblePagesKey: 'app/popupVisiblePages' as const,
|
visiblePagesKey: 'app/popupVisiblePages' as const,
|
||||||
pageOrderKey: 'app/popupPageOrder' as const,
|
pageOrderKey: 'app/popupPageOrder' as const,
|
||||||
};
|
};
|
||||||
}, [entryType]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RouterProvider
|
<RouterProvider
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useRouter } from '@/providers/RouterProvider';
|
import { useRouter } from '@/providers/RouterProvider';
|
||||||
import { getFeatureByKey } from '@/config/features';
|
import { getFeatureByKey } from '@/config/features';
|
||||||
import type { PageType } from '@/types/storage';
|
import type { PageType } from '@/types/storage';
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { useI18n } from '@/utils/chromeI18n';
|
import { useI18n } from '@/utils/chromeI18n';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
@@ -9,21 +8,17 @@ export default function Index() {
|
|||||||
const { navigateTo, visiblePages, pageOrder, recentlyUsedTools } = useRouter();
|
const { navigateTo, visiblePages, pageOrder, recentlyUsedTools } = useRouter();
|
||||||
const { t } = useI18n(['features']);
|
const { t } = useI18n(['features']);
|
||||||
|
|
||||||
const visibleSet = useMemo(() => new Set<string>(visiblePages), [visiblePages]);
|
const visibleSet = new Set<string>(visiblePages);
|
||||||
|
|
||||||
const visibleFeatures = useMemo(() => {
|
const visibleFeatures = pageOrder
|
||||||
return pageOrder
|
|
||||||
.filter((key) => visibleSet.has(key))
|
.filter((key) => visibleSet.has(key))
|
||||||
.map((key) => ({ key, feature: getFeatureByKey(key) }))
|
.map((key) => ({ key, feature: getFeatureByKey(key) }))
|
||||||
.filter((item) => item.feature?.themeColorKey && item.feature.icon != null);
|
.filter((item) => item.feature?.themeColorKey && item.feature.icon != null);
|
||||||
}, [pageOrder, visibleSet]);
|
|
||||||
|
|
||||||
const recentFeatures = useMemo(() => {
|
const recentFeatures = recentlyUsedTools
|
||||||
return recentlyUsedTools
|
|
||||||
.filter((key) => visibleSet.has(key))
|
.filter((key) => visibleSet.has(key))
|
||||||
.map((key) => ({ key, feature: getFeatureByKey(key) }))
|
.map((key) => ({ key, feature: getFeatureByKey(key) }))
|
||||||
.filter((item) => item.feature?.themeColorKey && item.feature.icon != null);
|
.filter((item) => item.feature?.themeColorKey && item.feature.icon != null);
|
||||||
}, [recentlyUsedTools, visibleSet]);
|
|
||||||
|
|
||||||
const showRecent = recentFeatures.length > 0;
|
const showRecent = recentFeatures.length > 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { getTextStats, type TextStats } from '@/utils/textStatistics';
|
import { getTextStats, type TextStats } from '@/utils/textStatistics';
|
||||||
import { useContextMenuData } from '@/utils/useContextMenuData';
|
import { useContextMenuData } from '@/utils/useContextMenuData';
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ export function useTextStatistics(): UseTextStatisticsReturn {
|
|||||||
|
|
||||||
useContextMenuData({ featureKey: 'textStatistics', onData: handleContextMenuData });
|
useContextMenuData({ featureKey: 'textStatistics', onData: handleContextMenuData });
|
||||||
|
|
||||||
const stats = useMemo(() => getTextStats(text), [text]);
|
const stats = getTextStats(text);
|
||||||
|
|
||||||
return { text, stats, setText };
|
return { text, stats, setText };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,4 @@
|
|||||||
import {
|
import { createContext, ReactNode, useCallback, useContext, useEffect, useState } from 'react';
|
||||||
createContext,
|
|
||||||
ReactNode,
|
|
||||||
useCallback,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useMemo,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import { browser } from 'wxt/browser';
|
import { browser } from 'wxt/browser';
|
||||||
import { storageUtil } from '@/utils/chromeStorage';
|
import { storageUtil } from '@/utils/chromeStorage';
|
||||||
|
|
||||||
@@ -141,12 +133,11 @@ export function ThemeModeProvider({ children }: ThemeModeProviderProps) {
|
|||||||
}
|
}
|
||||||
}, [resolvedMode]);
|
}, [resolvedMode]);
|
||||||
|
|
||||||
const contextValue = useMemo(
|
return (
|
||||||
() => ({ mode, resolvedMode, setMode }),
|
<ThemeModeContext.Provider value={{ mode, resolvedMode, setMode }}>
|
||||||
[mode, resolvedMode, setMode],
|
{children}
|
||||||
|
</ThemeModeContext.Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
return <ThemeModeContext.Provider value={contextValue}>{children}</ThemeModeContext.Provider>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useThemeMode(): ThemeModeContextType {
|
export function useThemeMode(): ThemeModeContextType {
|
||||||
|
|||||||
Reference in New Issue
Block a user