When optimizing React components in this Next.js 15 dashboard:
- •
Choose the right component type:
- •Default to Server Components (no "use client")
- •Use Client Components only when needed:
- •Using React hooks (useState, useEffect, useContext)
- •Using browser APIs (localStorage, window)
- •Using event handlers (onClick, onChange)
- •Using libraries that require client-side execution
- •
Minimize client-side JavaScript:
tsx// Good: Server Component (default) export default function StaticContent() { return <div>Content</div>; } // Use client only when necessary "use client"; export default function InteractiveContent() { const [state, setState] = useState(false); return <div onClick={() => setState(!state)}>Content</div>; } - •
Optimize re-renders with React.memo and useMemo:
tsximport { memo, useMemo } from "react"; // Memoize expensive computations const ExpensiveComponent = memo(function ExpensiveComponent({ data }) { const processedData = useMemo(() => { return data.map(item => expensiveOperation(item)); }, [data]); return <div>{processedData}</div>; }); - •
Use dynamic imports for large components:
tsximport dynamic from "next/dynamic"; const HeavyChart = dynamic(() => import("@/components/HeavyChart"), { loading: () => <p>Loading chart...</p>, ssr: false // Disable SSR if component uses browser APIs }); - •
Optimize images with next/image:
tsximport Image from "next/image"; <Image src="/image.png" alt="Description" width={500} height={300} priority // For above-the-fold images /> - •
Prevent unnecessary effect executions:
tsx// Include all dependencies useEffect(() => { fetchData(id); }, [id]); // Specify dependencies // Cleanup side effects useEffect(() => { const subscription = subscribe(); return () => subscription.unsubscribe(); }, []); - •
Type safety for better performance:
- •Use explicit TypeScript interfaces
- •Avoid
anytype - •Enable strict mode in tsconfig.json
- •
Component splitting:
- •Keep components focused on single responsibility
- •Extract reusable logic to custom hooks
- •Split large components into smaller ones
- •
Leverage Turbopack (Next.js 15):
- •Use
npm run devwhich automatically uses Turbopack - •Faster builds and hot module replacement
- •Use
Examples
Convert client component to server component
tsx
// Before (unnecessarily client-side)
"use client";
export default function StaticCard() {
return <Card>Static Content</Card>;
}
// After (server component)
export default function StaticCard() {
return <Card>Static Content</Card>;
}
Optimize chart rendering
tsx
"use client";
import { memo, useMemo } from "react";
import { LineChart, Line } from "recharts";
export const OptimizedChart = memo(function OptimizedChart({ data }) {
const colors = useChartColors();
// Memoize processed data
const chartData = useMemo(() => {
return data.map(item => ({
name: item.label,
value: item.total
}));
}, [data]);
return (
<LineChart data={chartData}>
<Line dataKey="value" stroke={colors.chart1} />
</LineChart>
);
});
Split a large component
tsx
// Before: One large component
export default function Dashboard() {
return (
<div>
<Header />
<Stats />
<Charts />
<Footer />
</div>
);
}
// After: Split into smaller, focused components
export default function Dashboard() {
return (
<div>
<DashboardHeader />
<DashboardStats />
<DashboardCharts />
<DashboardFooter />
</div>
);
}
// Each component in its own file
// Easier to maintain, optimize, and test
Related Files
- •
next.config.ts - •
tsconfig.json - •
src/components/DashboardCharts.tsx
Related Skills
- •
create-dashboard-page - •
add-chart