Server Components در Next.js 14 حجم باندل (bundle size) را تقریباً ۶۰٪ کاهش می‌دهند و زمان اولین نمایش (first-paint) را در یک صفحه وبلاگ معمولی به زیر ۲۰۰ میلی‌ثانیه می‌رسانند؛ این یعنی کاربران محتوا را سریع‌تر می‌بینند و موتورهای جستجو HTML کاملاً رندر شده را دریافت می‌کنند.

نسخه جدید، مدل اجرای پیش‌فرض را برای اپلیکیشن‌های React که با Next.js ساخته شده‌اند، تغییر می‌دهد. در حالی که پیش از این هر کامپوننت به مرورگر ارسال می‌شد، اکنون توسعه‌دهندگان می‌توانند بخش‌هایی از رابط کاربری (UI) را به عنوان «Server Components» علامت‌گذاری کنند تا فقط در سمت سرور اجرا شوند. کد مربوط به این کامپوننت‌ها هرگز به کلاینت نمی‌رسد و مرورگر را فقط با بخش‌هایی که به تعامل (interactivity) نیاز دارند، مواجه می‌کند.

چرا این تغییر اهمیت دارد

توسعه‌دهندگان React مدت‌هاست که با سه مشکل به‌هم‌پیوسته دست‌وپنجه نرم می‌کنند: هجوم درخواست‌های شبکه، باندل‌های سنگین JavaScript و بارگذاری کند صفحات. این مسائل همچنین به SEO آسیب می‌زنند، زیرا HTML اولیه ارسال شده به خزنده‌ها (crawlers) اغلب خالی است و ربات‌های جستجو را مجبور می‌کند منتظر Hydration سمت کلاینت بمانند. Next.js 14 با انتقال کارهای سنگینِ مربوط به داده‌ها از کلاینت، با علت اصلی این مشکل مقابله می‌کند.

تفاوت Server Components با مدل قدیمی

  • Server Components – در سرور اجرا می‌شوند، داده‌ها را واکشی (fetch) می‌کنند، با پایگاه‌های داده ارتباط برقرار می‌کنند و HTML ساده خروجی می‌دهند. کد JavaScript آن‌ها هرگز از شبکه عبور نمی‌کند.
  • Client Components – در مرورگر باقی می‌مانند و تعاملات UI مانند کلیک روی دکمه‌ها، ارسال فرم‌ها یا هر کامپوننتی که از React state یا effects استفاده می‌کند را مدیریت می‌کنند.

این فریم‌ورک این تفکیک را با یک دستور ساده اعمال می‌کند. افزودن use client در بالای یک فایل به Next.js می‌گوید که با آن کامپوننت فقط به عنوان سمت کلاینت رفتار کند. هر چیزی که فاقد این علامت باشد، به صورت پیش‌فرض یک Server Component محسوب می‌شود.

اعداد و ارقام در دنیای واقعی

یک آزمایش سریع روی صفحه یک وبلاگ شخصی، تأثیر این تغییر را نشان می‌دهد. پس از انتقال عملیات fetch به یک Server Component و اجازه دادن به سرور برای رندر کردن لیست به صورت HTML استاتیک، حجم باندل JavaScript حدود ۶۰٪ کاهش یافت و صفحه در کمتر از ۲۰۰ میلی‌ثانیه رندر شد.

یک الگوی لایه‌بندی کاربردی

  1. لایه پایین (Server) – داده‌ها را از APIها یا پایگاه‌های داده دریافت می‌کند. هرگونه منطق خصوصی (private logic) را اینجا نگه دارید؛ این کد هرگز از سرور خارج نمی‌شود.
  2. لایه میانی (Server) – داده‌های خام را به مارک‌آپ HTML خالص تبدیل می‌کند. این لایه همچنان می‌تواند از سینتکس JSX در React استفاده کند اما فقط در سمت سرور باقی می‌ماند.
  3. لایه بالا (Client) – ویجت‌های کوچک و مجزا را برای تعامل (interactivity) وارد می‌کند. نمونه‌های رایج شامل دکمه‌های «لایک»، فرم‌های کامنت یا منوهای کشویی هستند که به state نیاز دارند.

پیروی از این سلسله‌مراتب باعث می‌شود بخش اصلی اپلیکیشن سبک باقی بماند و در عین حال، حس پویایی (dynamic) مورد انتظار کاربران حفظ شود.

مراحلی که می‌توانید از امروز امتحان کنید

  1. کد خود را برای یافتن کامپوننت‌هایی که صرفاً از useEffect برای واکشی داده‌ها استفاده می‌کنند، اسکن کنید.
  2. فراخوانی fetch را به یک Server Component جدید منتقل کنید و اجازه دهید مارک‌آپ رندر شده را بازگرداند.
  3. برای هر عنصر تعاملی که باقی مانده است، یک کامپوننت کلاینت حداقلی بسازید (عبارت use client را در بالا اضافه کنید).
  4. دوباره bundle analyzer خود را اجرا کنید؛ باید شاهد کاهش محسوس در حجم فایل‌ها باشید.

از پراکندن use client در همه جا خودداری کنید. اگر یک کامپوننت به React state، context یا هوک‌های چرخه حیات (lifecycle hooks) وابسته نیست، آن را به عنوان یک Server Component رها کنید. هرچه کد بیشتری را از کلاینت دور نگه دارید، حجم دانلود کمتر و سرعت صفحه بیشتر خواهد بود.

نکته کلیدی: با انتقال واکشی داده‌ها و رندرینگ سنگین به سرور، Next.js 14 به شما اجازه می‌دهد JavaScript بسیار کمتری ارسال کنید، HTML کاملاً رندر شده را فوراً تحویل دهید و تعامل را در جاهایی که واقعاً اهمیت دارد حفظ کنید. نتیجه، یک تجربه وب سریع‌تر و سبک‌تر است که هم به کاربران و هم به موتورهای جستجو سود می‌رساند.