• صفحه اصلی
  • درباره من
  • مهارت‌های ایجنت
  • پروژه‌ها
  • بلاگ
  • مشاوره
  • تماس با من
مشاورهرزومه
Naser Rasouli

نویسنده

Naser Rasouli

توسعه‌دهنده فرانت‌اند؛ اینجا تجربه‌ها و یادداشت‌های واقعی‌ام از پروژه‌ها را می‌نویسم.

GitHubLinkedIn

آخرین نوشته‌ها

Optimistic UI در React بدون باگ‌های رایج
2026-09-11•1 دقیقه مطالعه

Optimistic UI در React بدون باگ‌های رایج

یک الگوی عملی برای Optimistic UI در React با useOptimistic، Transition، rollback و همگام‌سازی نتیجه واقعی سرور بدون ساخت state موازی و پیچیده.

JavaScript SEO برای React: Google دقیقاً چه چیزی می‌بیند؟
2026-09-10•1 دقیقه مطالعه

JavaScript SEO برای React: Google دقیقاً چه چیزی می‌بیند؟

راهنمای عملی JavaScript SEO در React؛ تفاوت crawl و render و index، انتخاب SSR یا prerender و جلوگیری از پنهان‌شدن محتوا و لینک‌ها پشت client rendering.

فرم‌های Type-safe در React با React Hook Form و Zod
2026-09-07•1 دقیقه مطالعه

فرم‌های Type-safe در React با React Hook Form و Zod

یک الگوی schema-first برای ساخت فرم‌های React با React Hook Form و Zod؛ از type inference و field array تا خطاهای API و مرز validation سمت کلاینت و سرور.

دیباگ INP در اپ‌های React از Field Data تا Profiler

دیباگ INP در اپ‌های React از Field Data تا Profiler

2026-09-10
reactperformanceinpweb-vitalsprofiling

دیباگ INP در اپ‌های React از Field Data تا Profiler

INP فقط یک عدد Lighthouse نیست. اگر کلیک، تایپ یا بازکردن یک منو برای کاربر دیر پاسخ می‌دهد، باید مسیر کامل interaction را بررسی کنید: event handler، محاسبات JavaScript، render و paint.

1. از Field Data شروع کنید

قبل از بهینه‌سازی، مشخص کنید مشکل واقعاً برای کاربران رخ می‌دهد یا فقط در یک تست مصنوعی دیده شده است. داده‌های واقعی را بر اساس route، device و interaction دسته‌بندی کنید. هدف این است که یک interaction مشخص برای بازتولید داشته باشید، نه اینکه کل اپ را «سریع‌تر» کنید.

2. interaction کند را بازتولید کنید

در DevTools Performance یک trace بگیرید و همان رفتار را تکرار کنید. به Long Taskها، handlerهای طولانی و فاصله بین input و paint بعدی توجه کنید.

click
  -> event handler
  -> state update
  -> React render
  -> style/layout
  -> paint

اگر بخش اصلی زمان قبل از render مصرف می‌شود، memo کردن کامپوننت‌ها احتمالاً درمان مسئله نیست.

3. handler را سبک نگه دارید

کارهای مستقل از پاسخ فوری UI را از مسیر interaction خارج کنید. parsing بزرگ، sort سنگین یا تبدیل داده حجیم نباید بدون دلیل داخل handler اجرا شود.

function handleSelect(id: string) {
  setSelectedId(id)
  // کار سنگین و غیرضروری را اینجا همزمان اجرا نکنید.
}

برای محاسبات CPU-heavy ابتدا کاهش حجم کار، cache کردن نتیجه معتبر یا انتقال کار به worker را بررسی کنید.

4. React Profiler را برای render بررسی کنید

اگر trace نشان می‌دهد render سهم قابل‌توجهی دارد، Profiler را باز کنید و ببینید کدام subtree دوباره render شده است و چرا. memo، useMemo و useCallback ابزار هدفمند هستند، نه تنظیمات پیش‌فرض.

نشانه‌های رایج:

  • Context بزرگی که با هر تغییر مصرف‌کننده‌های زیادی را render می‌کند؛
  • object یا callback جدیدی که memoization موجود را بی‌اثر می‌کند؛
  • state بالاتر از سطح مالک واقعی آن نگهداری می‌شود؛
  • list بزرگ بدون virtualization رندر می‌شود.

5. Transition را فقط برای کار non-urgent استفاده کنید

اگر یک update برای feedback فوری لازم نیست، می‌توان آن را در transition قرار داد تا updateهای فوری اولویت داشته باشند.

import { startTransition } from "react"

function handleSearch(value: string) {
  setInput(value)
  startTransition(() => {
    setFilter(value)
  })
}

Transition محاسبه سنگین JavaScript را جادویی سریع نمی‌کند؛ فقط scheduling updateهای React را تغییر می‌دهد.

6. بعد از هر تغییر دوباره اندازه بگیرید

هر optimization باید یک فرضیه داشته باشد: «این handler 80ms کار sync دارد» یا «این Context باعث render شدن 300 row می‌شود». بعد از تغییر همان interaction را دوباره trace کنید و نتیجه را با baseline مقایسه کنید.

چک‌لیست نهایی

  1. interaction واقعی و route مشکل‌دار را پیدا کنید؛
  2. Performance trace بگیرید؛
  3. زمان handler، render و layout/paint را از هم جدا کنید؛
  4. بزرگ‌ترین هزینه را اصلاح کنید؛
  5. Profiler را فقط وقتی render مشکوک است وارد کنید؛
  6. روی دستگاه ضعیف‌تر و Field Data دوباره اعتبارسنجی کنید.

بهینه‌سازی INP زمانی قابل اعتماد است که از یک interaction واقعی شروع شود و با اندازه‌گیری همان interaction تمام شود.