Back to list
CeamKrier

performance-optimization

by CeamKrier

Browser-based tool to combine and format multiple files for optimal use with AI language models (ChatGPT, Claude, etc.).

2🍴 0📅 Jan 17, 2026

SKILL.md


name: performance-optimization description: Optimize React application performance with lazy loading, code splitting, memoization, and virtualization. Use when addressing slow renders, large bundles, or memory issues.

Performance Optimization

When to Use This Skill

Use when:

  • Initial load time is too slow
  • Components re-render unnecessarily
  • Rendering large lists or data sets
  • Bundle size is too large
  • Memory usage is high

Code Splitting & Lazy Loading

React.lazy for Route-based Splitting

import { lazy, Suspense } from 'react';

const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));

function App() {
  return (
    <Suspense fallback={<LoadingSpinner />}>
      <Routes>
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/settings" element={<Settings />} />
      </Routes>
    </Suspense>
  );
}

Named Exports with Lazy

// For components not using default export
const LazyComponent = lazy(() =>
  import('./components').then(module => ({
    default: module.SpecificComponent
  }))
);

Preloading on Hover

const DashboardLazy = lazy(() => import('./Dashboard'));

function NavLink() {
  const preload = () => {
    import('./Dashboard'); // Starts loading on hover
  };

  return (
    <Link to="/dashboard" onMouseEnter={preload}>
      Dashboard
    </Link>
  );
}

Memoization

React.memo for Components

interface ExpensiveComponentProps {
  data: Data;
  onAction: (id: string) => void;
}

// Only re-renders when props change (shallow comparison)
export const ExpensiveComponent = React.memo(
  function ExpensiveComponent({ data, onAction }: ExpensiveComponentProps) {
    return <div>{/* expensive render */}</div>;
  }
);

// With custom comparison
export const CustomMemoComponent = React.memo(
  ExpensiveComponent,
  (prevProps, nextProps) => {
    return prevProps.data.id === nextProps.data.id;
  }
);

useMemo for Expensive Calculations

function DataProcessor({ items, filter }: Props) {
  // Only recalculates when items or filter change
  const filteredItems = useMemo(() => {
    return items.filter(item =>
      item.name.includes(filter)
    ).sort((a, b) => a.name.localeCompare(b.name));
  }, [items, filter]);

  return <List items={filteredItems} />;
}

useCallback for Stable References

function Parent({ items }: Props) {
  // Stable reference, doesn't change between renders
  const handleClick = useCallback((id: string) => {
    console.log('Clicked:', id);
  }, []); // Empty deps = never changes

  return (
    <>
      {items.map(item => (
        <MemoizedChild
          key={item.id}
          onClick={handleClick}
        />
      ))}
    </>
  );
}

List Virtualization

Using react-window

import { FixedSizeList } from 'react-window';

interface ItemData {
  items: Item[];
  onSelect: (id: string) => void;
}

function VirtualList({ items, onSelect }: ItemData) {
  const Row = ({ index, style }: { index: number; style: React.CSSProperties }) => (
    <div style={style} onClick={() => onSelect(items[index].id)}>
      {items[index].name}
    </div>
  );

  return (
    <FixedSizeList
      height={400}
      width="100%"
      itemCount={items.length}
      itemSize={50}
    >
      {Row}
    </FixedSizeList>
  );
}

Debouncing & Throttling

function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debouncedValue;
}

// Usage
function SearchInput() {
  const [query, setQuery] = useState('');
  const debouncedQuery = useDebounce(query, 300);

  useEffect(() => {
    if (debouncedQuery) {
      search(debouncedQuery);
    }
  }, [debouncedQuery]);
}

Bundle Analysis

# Vite
npx vite-bundle-visualizer

# Webpack
npx webpack-bundle-analyzer stats.json

Performance Checklist

  • Use React.lazy for route-level code splitting
  • Wrap expensive components with React.memo
  • Use useMemo for expensive calculations
  • Use useCallback for callback props passed to memoized children
  • Virtualize lists with >100 items
  • Debounce input handlers
  • Lazy load images below the fold
  • Split vendor chunks from app code

Score

Total Score

65/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon