Next.js یک فریم‌ورک React است که به دلیل پشتیبانی از رندر سمت سرور (Server-Side Rendering) در برنامه‌های React بسیار مورد استفاده قرار گرفته است. این فریم‌ورک علاوه بر SSR ابزارهای زیادی را ارائه می‌دهد که کیفیت برنامه‌هایی که با React می‌سازیم را بهبود می‌بخشد. در این مقاله قصد داریم تا برخی از این مفاهیم و تکنیک‌های کاربردی که در Next.js استفاده می‌شود را مورد بررسی قرار دهیم.

رندر سمت سرور و Pre-rendering با Next.js

توسعه‌دهندگان به طور گسترده از فریم‌ورک Next.js برای پشتیبانی از رندر سمت سرور (SSR) در برنامه‌های React خود استفاده می‌کنند. این فریم‌ورک علاوه بر SSR ابزارهای زیادی برای به بهبود کیفیت برنامه‌های ساخته شده با React ارائه می‌دهد.

هدف ما در این بخش این است که برخی از مفاهیم و تکنیک‌های اصلی Next.js بررسی کنیم. برای این کار ابتدا با بررسی مزایای SSR شروع می‌کنیم و سپس به این موضوع که SSR و  پیش‌رندر در این فریم‌ورک چگونه کار می‌کند می‌پردازیم. علاوه بر این، برخی از کامپوننت‌های اصلی که در Next.js مورد استفاده قرار می‌گیرند را بررسی خواهیم کرد.

رندر سمت سرور چیست؟

وب با SSR شروع شد. هنگامی که ما فایل‌های برنامه خود را روی سرور آپلود می‌کنیم، مرورگرهای دیگر که کلاینت نام دارند می‌توانند آن‌ها را درخواست کنند.

برای مثال وقتی به آدرس /contactمی‌رویم کلاینت contact.htmlرا از سرور درخواست می‌کند. این فایل همچنین با منابع مرجع دیگری مانند تصاویر، stylesheetها و موارد دیگر همراه است. پس از دریافت فایل‌ها، مرورگر صفحه را به کاربر نمایش می‌دهد و برای هر navigationای مرورگر یک صفحه کاملاً جدید از سرور درخواست می‌کند.

موارد زیادی در وب وجود دارد. با استفاده از متد اصلی، زمانی که به یک صفحه‌ وب می‌رویم قبل از نمایش هر چیزی باید منتظر بمانیم تا مرورگر فایل‌های آن صفحه را دانلود کند. اما امروزه یک متد جدید برای ایجاد اپلیکیشن‌ها وجود دارد و آن SPA (single-page application) می‌باشد.

SPAها وب اپلیکیشن‌ها و یا وب‌سایت‌هایی هستند که تنها یک document وب را از سرور لود کرده و سپس به صورت پویا تعیین می‌کنند که چه چیزی در مسیرهای مختلف نمایش داده شود. این روش به این معنی است که مرورگر فقط یک بار درخواست را به سرور ارسال می‌کند. در نتیجه سریع‌تر است زیرا مرورگر از درخواست مجدد بعد از درخواست اول اجتناب می‌کند.

SPAها با تکنیک CSR (client-side rendering) کار می‌کنند. در CSR، جاوااسکریپت روی کلاینت صفحات وب را رندر می‌کند. برای هر مسیر، جاوااسکریپت المنت‌های آن مسیر را رندر می‌کند. در مقابل، SSR المنت‌های مختلف را برای مسیرهای مختلف از سرور رندر کرده و کار کم‌تری را برای کلاینت باقی می‌گذارد.

یک نکته بسیار خوب در مورد SSR این است که به بهینه‌سازی موتورهای جستجو (SEO) نیز کمک می‌کند. با SSR، صفحه وب برای هر URL از سرور پردازش می‌شود و ایندکس کردن صفحات مختلف وب‌سایت را برای موتورهای جستجو آسان‌تر می‌کند.

از آنجایی که در SSR برای دریافت محتوای جدید برای یک صفحه دیگر همیشه باید منتظر لود مجدد صفحه باشیم ممکن است روش کندی به نظر برسد، اما فریمورک‌هایی مانند Next.js فرآیند سریع‌تری برای لذت بردن از ویژگی‌های SSR همانند مزایای سمت کلاینت دارند. در ادامه مقاله به بررسی این مفاهیم در Next.js خواهیم پرداخت.

مفهوم Pre-rendering چیست؟

Next.js یک ویژگی به نام pre-rendering را ارائه می‌دهد. با پیش‌رندر کردن از سرور، مرورگر یک صفحه HTML دریافت می‌کند که یک رابط کاربری را حتی بدون جاوااسکریپت نشان می‌دهد.

در React ساده که در رندر سمت کلاینت کار می‌کند، کاربر برای رندر و نمایش یک صفحه باید جاوااسکریپت را فعال کند. اما Next.js زمانی که حتی جاوااسکریپت فعال نباشد هم صفحه در مرورگر نشان داده می‌شود. با این حال، برای اینکه در و‌ب‌سایت تعاملی وجود داشته باشد(مانند باز کردن یک لینک) نیاز به جاوااسکریپت وجود دارد.

pre-rendering تکنیکی است که یک صفحه را از قبل رندر می‌کند. مفهوم «از قبل» می‌تواند به دو مورد در Next.js اشاره کند: ساخت سایت به شکل استاتیک و یا رندر سمت سرور.

تولید سایت به شکل استاتیک

فرآیند pre-rendering تولید استاتیک صفحات سایت ما را هنگام ساخت برنامه (به عنوان مثال npm run build) برعهده دارد. این فرآیند مخصوص محتوای ثابت برنامه می‌باشد. به عنوان مثال می‌توانیم از تولید استاتیک برای بخش پست‌های وبلاگ استفاده کنیم. در طول این مدت، Next.js فایل‌های HTML را برای هر صفحه پست وبلاگ از قبل تولید می‌کند که ممکن است از یک API بوده و یا به صورت دستی در برنامه نوشته شده باشد.

نتیجه‌ای که از تعریف این مفاهیم به دست می‌آید این است که Next.js می‌تواند به عنوان یک ابزار تولیدکننده سایت استاتیک، مشابه Gatsby مورد استفاده قرار بگیرد.

استفاده از navigation سمت کلاینت (با استفاده از کامپوننت Linkکه در ادامه با آن آشنا خواهیم شد) برای این صفحات ثابت باعث می‌شود تا سایت ما بسیار سریع‌تر باشد. زیرا Next.js محتوا را برای صفحات دیگر وبلاگ نیز از پیش fetch می‌کند. این fetch کردن از قبل باعث می‌شود که جابه‌جایی بین صفحات به سرعت انجام شود.

همچنین می‌توانیم تولید سایت به شکل استاتیک را در Next.js با استفاده از توابع asynchronous مانند getStaticProps (برای fetch کردن داده‌ها در زمان ساخت) و getStaticPaths (برای توصیف مسیرها در صفحات پویا) انجام دهیم.

رندر سمت سرور

نکته‌ای که وجود دارد این است که همه محتواها نمی‌توانند ثابت باشند. به عنوان مثال، فیس‌بوک یا توییتر داده‌هایی دارند که دائماً در حال تغییر بوده و به احتمال زیاد هنگام رفرش کردن تغییر خواهند کرد. مفهوم پیش رندر SSR در این شرایط کار می‌کند. با استفاده از getServerSideProps (که یک تابع export شده در یک صفحه برای fetch کردن داده‌ها در صورت درخواست صفحه است) می‌توانیم داده‌ها را از یک API یا سرویس خارجی درخواست کنیم. این داده‌ها به صفحه ما منتقل شده و کد صفحه را رندر می‌کند و به مرورگر تحویل می‌دهد.

همانطور که قبلاً هم به آن اشاره کردیم، مرورگر هر آنچه را که از سرور دریافت می‌کند را حتی بدون جاوااسکریپت نمایش می‌دهد، اما برای تعاملات و سایر عملکردها به جاوا‌اسکریپت نیاز دارد.

کامپوننت‌های Next.js برای ساخت برنامه‌های React

هدف سازندگان Next.js این بود که برنامه‌ها برای موتورهای جستجو بهینه شوند و همچنین بهینه‌سازی کلی برنامه به شکل یکپارچه صورت گیرد. از آنجایی که این کارها را می‌توانیم بدون این کامپوننت‌ها هم انجام دهیم اما استفاده از آن‌ها مزایایی دارد از جمله اینکه باعث می‌شود تا برنامه‌های ما سریع‌تر، کارآمدتر و بهینه‌تر باشند.

سه کامپوننت اصلی در Next.js وجود دارد که عبارتند از کامپوننت Link، کامپوننت Image و کامپوننت Head که در ادامه به بررسی مفاهیم هر یک از آن‌ها می‌پردازیم.

کامپوننت Link

Next.js از کامپوننت Linkبرای navigation در سمت کلاینت استفاده می‌کند، یعنی جابه‌جایی بین صفحات که جاوااسکریپت در سمت کلاینت آن را مدیریت می‌کند. در ادامه نحوه استفاده از این کامپوننت را بررسی می‌کنیم:

<Link href="/contact">
  <a>Contact us</a>
</Link>

توجه به این نکته لازم است که کامپوننت به عنوان یک تگ anchor کار نمی‌کند بلکه فقط به عنوان یک wrapper برای تگ anchor مورد استفاده قرار می‌گیرد.

هنگامی که با استفاده از این کامپوننت به صفحه contact می‌رویم، مرورگر مجدداً لود نمی‌شود و درخواست دیگری برای مسیر /contactاز سرور ارائه نمی‌کند. در صفحه فعلی (مثلاً صفحه اصلی)، هنگامی که لینک «تماس با ما» که در داخل کامپوننت Linkقرار گرفته است در viewport دیده می‌شود، حتی قبل از اینکه کاربر روی آن کلیک کند، Next.js کد آن صفحه را که در حال تولید است، fetch می‌کند. هنگامی که کاربر روی لینک کلیک می‌کند، صفحه contact به سرعت و بدون درخواست اضافی از سرور لود می‌شود.

در مقابل، وقتی مستقیماً از یک تگ anchor استفاده می‌کنیم، مرورگر را مجددا لود کرده و از fetch کردن اولیه داده‌ها جلوگیری می‌کنیم.

کامپوننت Image

استفاده از المنت imgاین امکان را به ما می‌دهد تا همه موارد از جمله responsiveness ،resizing، انتخاب دستی فرمت‌های مختلف تصویر و غیره را به طور مستقل برای برنامه خود مدیریت کنیم. کامپوننت Imageهمه بهینه‌سازی‌ها را برای ما انجام می‌دهد. در ادامه نحوه استفاده از آن را بررسی می‌کنیم:

<Image src="source-to-image" width={600} height={600} alt="Alt text of image" />

مقادیر width و height بر حسب پیکسل هستند. یا اینکه می‌توانیم از layout prop استفاده کنیم که می‌تواند یکی از موارد زیر باشد:

کامپوننت Image تکنیک‌های کش و بهینه‌سازی مانند responsiveness و resizing را روی تصاویر انجام می‌دهد و بسته به پشتیبانی مرورگر چندین قالب تصویر را ارائه می‌دهد. این کامپوننت همچنین به طور پیش‌فرض از lazy-load استفاده می‌کند و در نتیجه بر زمان بارگذاری صفحه ما تأثیر منفی نمی‌گذارد.

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

کامپوننت Head

کامپوننت Headراه آسان‌تری برای پر کردن و به‌روزرسانی تگ head برای صفحات ما فراهم می‌کند. در ادامه نحوه استفاده از آن را بررسی می‌کنیم:

<Head>
  <title>My portfolio</title>
  <meta
    name="description"
    content="My portfolio website showing all my completed works"
  />
</Head>

با استفاده از این کامپوننت می‌توانیم تگ head صفحه را با عناصر مختلف مورد نیاز برای سئو و navigation یکپارچه سمت کلاینت خود پر کنیم.

جمع‌بندی

تیم سازنده فریم‌ورک Next.js همچنان به بهینه سازی و بهبود عملکرد برای وب اپلیکیشن‌ها ادامه می‌دهد و همین موضوع باعث می‌شود تا این فریم‌ورک روزبه‌روز از محبوبیت بیشتری برخوردار شود.

در این مقاله سعی کردیم تا مفاهیم و ابزارهای کاربردی را که Next.js را به توسعه وب مرتبط می‌کند، بررسی کنیم. اکنون که درباره Next.js و قابلیت‌های رندر آن بیشتر می‌دانیم، می‌توانیم این عناصر را در وب‌سایت‌ها و برنامه‌های بعدی خود مورد استفاده قرار دهیم.