Performance Optimization
افزایش سرعت، کاهش رندرهای اضافه، و رساندن اپلیکیشن به حداکثر بازدهی
بهینهسازی عملکرد به مجموعهای از روشها و ابزارها گفته میشود که هدف آنها افزایش سرعت، کاهش مصرف منابع (CPU، حافظه، شبکه) و ارتقای تجربهٔ کاربر (UX) است.
در React و Next.js این موضوع اهمیت دوچندان دارد چون ساختار کامپوننتمحور و رندر سمت سرور/کلاینت میتواند تأثیر بزرگی روی سرعت صفحه بگذارد.
هدف اصلی:
کاهش زمان بارگذاری اولیه (Initial Load Time)
بهبود سرعت تعامل کاربر (TTI – Time To Interactive)
افزایش روانی رابط کاربری (FPS – Frame Per Second)
کنترل مصرف حافظه و CPU
بهبود شاخصهای Core Web Vitals (LCP, FID, CLS)
تکنیکهای اصلی در React.js
1. جلوگیری از رندرهای غیرضروری:
- جلوگیری از رندر مجدد کامپوننت با React.memo
const UserCard = React.memo(({ name }) => <div>{name}</div>);
- حفظ مقدار محاسبهشده با useMemo
const heavyValue = useMemo(() => calculateHeavyValue(data), [data]
);
- حفظ تابع با useCallback تا رفرنس توی dependency تغییر نکنه
const handleClick = useCallback(() => doSomething(), [someDependency]
);
نکته: برای تشخیص رندرهای اضافه از ابزارهایی مثل React Developer Tools Profiler استفاده کن.
2. تقسیم کد (Code Splitting) و Lazy Loading
- به جای اینکه تمام کدها رو در یک باندل لود کنیم، بخشهایی رو که موردنیاز نیست Lazy لود کنیم تا سرعت اولیه بالا بره.
// React.lazy برای کامپوننتهای سنگین
const HeavyComponent = React.lazy(() => import("./HeavyComponent"));
function App() {
return (
<Suspense fallback={<Spinner />}>
<HeavyComponent />
</Suspense>
);
}
نتیجه: فایل JS کوچکتر، بارگذاری سریعتر، و زمان اجرای کمتر.
3. بهینهسازی State Management:
از Zustand, یا Jotai برای state سادهتر استفاده کن.
استفاده از Redux Toolkit برای stateهای پیچیده تر
استفاده از Context تنها برای دادههایی استفاده بشه که مشترک بین چند بخش هستن.
در صورت نیاز به Context سنگین، از context selectors یا use-context-selector بهره ببر تا همهی مصرفکنندهها با هم رندر نشن.
تکنیکهای اصلی در Next.js
1. استراتژیهای رندر هوشمند:
// SSG (Static Site Generation --- استاتیک - بهترین عملکرد)
export async function getStaticProps() {
const data = await getData();
return { props: { data } };
}
// SSR (Server-Side Rendering --- برای گرفتن داده در هر درخواست از سرور )
export async function getServerSideProps() {
const data = await getData();
return { props: { data } };
}
// ISR (Incremental Static Regeneration --- پویا - وقتی داده real-time نیاز است)
export async function getServerSideProps() {
const data = await getFreshData();
return { props: { data }, revalidate: 60 }; // هر ۶۰ ثانیه بهروزرسانی
}
همیشه قبل از انتخاب استراتژی رندر، نوع داده (ایستاده یا پویا) رو بسنج.
2. بهینهسازی تصاویر با next/image
این کامپوننت واقعاً یکی از شاهکارهای Next.js برای Performance هست
خودش بهصورت خودکار:
- اندازهٔ تصاویر رو بر اساس نمایشگر تغییر میده (Responsive resizing)
- فرمت مدرن مثل WebP انتخاب میکنه
- و Lazy-load و Blur Placeholder داره
import Image from "next/image";
<Image
src="/photo.jpg"
alt="تصویر یک کوه زیبا"
width={800}
height={400}
priority // برای تصاویر مهم مثل Hero section
placeholder="blur"
/>;
3. تقسیم کد مسیرها و کامپوننتها
- خوده Next.js به صورت خودکار برای هر route یک باندل جدا میسازه.
- اما برای کنترل دستی هم میتونی از next/dynamic کمک بگیری:
import dynamic from "next/dynamic";
const MapComponent = dynamic(() => import("../components/Map"), {
ssr: false, // فقط در کلاینت لود شود
loading: () => <p>در حال بارگذاری...</p>,
});
تکنیک رایج: کامپوننتهایی مثل نقشهها، چارتها یا ویرایشگرها رو فقط هنگام نیاز لود کن.
ابزارهای اندازهگیری Performance
1. Web Vitals:
- بخش Core Web Vitals متریکهای کلیدی گوگل برای تجربهٔ واقعی کاربر هستن:
- LCP (Largest Contentful Paint)
- CLS (Cumulative Layout Shift)
- FID (First Input Delay)
import { reportWebVitals } from "next/web-vitals";
export function reportWebVitals(metric) {
console.log(metric.name, metric.value);
}
2. Bundle Analyzer
- تشخیص اینکه کد ما چقدر سنگینه و چیا باعث حجم زیاد Bundle شدن:
npm i @next/bundle-analyzer
# package.json
"scripts": {
"analyze": "ANALYZE=true next build"
}
# اجرا:
npm run analyze
خروجی گرافی نشون میده کِی باید lazy-load اضافه کنیم و چه پکیجهایی زیاد فضا میگیرن.
| ابزار پیشنهادشده | تکنیک کلیدی | حوزه |
|---|---|---|
| React.memo, useMemo, useCallback | جلوگیری از رندرهای اضافه، استفاده از memoization | React |
| SSG / ISR / SSR | انتخاب درست استراتژی رندر | Next.js |
| next/image | بهینهسازی خودکار | تصاویر |
| dynamic(), @next/bundle-analyzer | تفکیک کد و تحلیل حجم | باندلها |
| Chrome DevTools, Web.Dev, Sentry | Web Vitals & Lighthouse | اندازهگیری عملکرد |
جمع بندی
خب Performance Optimization یک فرآیند مداوم است، نه یک کار یکباره.
هر تصمیم در:
- معماری کامپوننتها
- استراتژی رندر
- مدیریت State
- و نحوه بارگذاری منابع
مستقیماً روی تجربه کاربر اثر میگذارد.
یک اپلیکیشن سریع:
- نرخ تبدیل بالاتری دارد
- کاربران بیشتری را حفظ میکند
- و از نظر سئو رتبه بهتری میگیرد
در نهایت، Performance نه فقط یک موضوع فنی، بلکه یک مزیت رقابتی محصول است.