محسن محمدی رهنما
محسن محمدی رهنما
خواندن ۹ دقیقه·۲ سال پیش

کاربرد CSR , SSG,SSR و ISR در Next js

سلام به همگی ، یه چند وقتی هست دارم در رابطه با next js مطالعه میکنم تا اینکه رسیدم به مبحث Page re-rendering در Next js و از اونجایی که پیدا کردن منابع فارسی در این خصوص بیشتر شبیه به یه جوک هست 😁 به همین خاطر تصمیم گرفتم خودم یه مقاله کاملا بومی سازی شده در این باره بنویسم . پس بزن بریم !

بزن بریم به زبان غربی
بزن بریم به زبان غربی

قبل اینکه بریم سراغ معرفی متد ها ، بیاین قبلش بیینیم اصلا next js چجوری عمل Rendering رو انجام میده یا اصلا Rendering یعنی چی؟!

منظور از Rendering در Nextjs

در واقع بخوام خلاصه بگم ، به عمل تبدیل کدهایی که (داخل پروژه React تون ) مینویسید و ارائه اون بصورت رابط کاربری HTML رو Redering میگن. عملیات Rendering هم میتونه سمت Server مدیریت بشه هم سمت Client و همینطور میتونه فقط زمان build صفحه عملیات Rendering انجام بشه یا به ازای هر بار Request یی که در زمان اجرا زده میشه .

درباره Pre-rendering

خب تا اینجای کار ما با مبحث Rendering آشنا شدیم ، حالا میخوام شما رو با یکی از قدرت های Nextjs آشناتون کنم، بله درسته Pre-rendering ، این دوستمون میاد چی کار میکنه ! میاد عملیات Fetching data (واکشی داده 😁) و انتقال Component های React به صفحات HTML مون رو قبل اینکه سمت Client برسه رو انجام میده . محشره مگه نه ?! یعنی کاربر دیگه لازم نیست منتظر باشه تا صفحه ی مورد نظرش ، اول کامل براش Load بشه بعد تازه اونموقع بتونه کل محتوای صفحه رو ببینه ! چون الان به لطف Nextjs همه چی سمت Server مدیریت شده . حالا الان باز توضیح میدم این حالت چه فرقی با حالت های قبلی داره.

تفاوت Client-Side Rendering با Pre-Rendering

در حالت معمول در React ، مرورگر شما برای اینکه بیاد UI رو بسازه، میاد یه پوسته HTML خام به همراه جاوااسکریپت های مورد نظر رو از سمت سرور میگیره بعد از اینکه جاوااسکریپت ها load شدن و همه چی گل و بلبل پیش رفت تازه اون موقع صفحه با محتواش بهتون نمایش داده میشه اگه بخوام کلی بگم ، همه چی سمت Client و مرورگر کاربر مدیریت میشه به این نوع Rendering میگن Client-side Rendering

Client-side Rendering
Client-side Rendering


ولی در نقطه ی مقابل اون یعنی Pre-rendering ، به ازای هر Request ی که میزنیم HTML صفحه مورد نظر به همراه فایل های Json و کدهای جاوااسکریپت توی اون صفحه لازم داریم، داخل Server ساخته میشه و درنهایت نتیجه سمت Clent ارسال میشه و شما توی مرورگرتون صفحه مورد نظرتون رو میبینین ، خب حالا دقیقا روال کلی کار به چه صورت هست؟!🤔

Pre-Rendering
Pre-Rendering

شما وقتی Request میزنید تا صفحه مورد نظرتون رو ببینید، UI اولیه صفحه سمت Server ساخته میشه و به شما نمایش داده میشه (بدون جاوااسکریپت) که در اصطلاح میگن non-interactive یا غیرتعاملی ، و در نهایت بعد از اینکه جاوااسکریپت های موردنظر دانلود و بارگزاری شدن نتیجه کامل تر رو مشاهده میکنید دراصل فرقش با Client-side Rendering توی همینه که شما در حالت قبلی تا زمانی که کل فایل ها چه HTML و جاوااسکریت و... کامل load نشن ، شما با صفحه سفید مواجه هستید و وقتی تماما فایل ها load شدن اون موقع میتونین صفحه کامل رو ببینین که درواقع همه اینه سمت مرورگر شما مدیریت میشه . حالا یه حرکت جالبی که Pre-Rendering داره اینه که ، میاد سریع یه UI اولیه از صفحه موردنظرتون رو بهتون نمایش میده تا شما نمایش اولیه صفحه رو داشته باشین در این حین میاد همزمان اون فایل های جاوااسکریپت و json و... که توی صفحه نیاز دارید رو بارگزاری میکنه به این حرکتش میگن Hydration که عجب حرکتیه ، شیر مادر، نان پدر حلالش 😄. بخش بعد یه خورده هیجان انگیزتر میشه ماجرا ، میخوام تک به تک متدهای Rendering رو براتون توضیح بدم 🤩.

درباره CSR

خب Client-side Rendering یا به اختصار CSR به عملیات دریافت داده (Fetching data) در سمت Client گفته میشه ، حالا آیا اصلا این متد بدرد بخور هست؟🤔 باید بگم برای زمانی که صفحه تون نیازی به SEO نداره که گوگل بخواد اون رو index کنه و یا صفحه تون نیاز به Pre-Render نداشته باشه و data هاش هر لحظه بروز نمیشن ، این متد میتونه گزینه مناسبی برای این شرایطی که خدمتتون عرض کردم باشه فقط یه نکته ای که خیلی حواستون باشه اینه که این روش تاثیر زیادی میتونه روی Performance داشته باشه بخصوص روی سرعت بارگزاری صفحه تون هست چون همه چی (Fetching data) سمت Client مدیریت میشه.

خب ما به دو صورت میتونیم عملیات Fetching data رو در CSRانجام بدیم اولی اینکه با useEffectاینکار رو بکنیم یعنی به این صورت که در تصویر پایین میبینید.

CSR with UseEffect
CSR with UseEffect


روش بعدی استفاده از SWR هست که خوده Next js اون رو خیلی پیشنهاد کرده به اصطلاح گفته میشه که highly recommended هست ، خب حالا چرا! چون با استفاده از این hook میتونیم عملیات Caching Revalidation , Focus tracking و... رو کاملا مدیریت کنیم و در واقع SWR خودش بصورت خودکار عملیات Caching رو برامون اجام میده و همینطور اگر data مون نیاز باشه که Revalidate خودش این کار رو برامون انجام میده . از بس که این hook گله..گل 😄 . اگه خواستین بیشتر درباره SWR بدونین ، میتونین اینجا دربارش کامل بخونین . تصویر پایین هم Fetching data با استفاده از همین Hook هست.

CSR with SWR
CSR with SWR


CSR
CSR


درباره SSR

حالا نقطه مقابل CSR متد دیگه هست به نام Server-Side Rendering یا به اختصار SSR ، حالا یعنی چی نقطه ی مقابل؟! یعنی اینکه شما وقتی میخواید صفحه مورد نظرتون SEO داشته و باشه و گوگل اون رو index کنه باید از این متد استفاده کنید . حالا به چه صورت ؟ عرض میکنم خدمتتون . شما وقتی میخواید صفحه تون SSR بشه نیاز به یک تابع دارید به نام getServerSideProps وقتی که از این تابع توی صفحه مون ما export بگیریم ، Nextjs اون صفحه رو SSR در نظر میگیره به ازای هر Request ی که زده میشه این صفحه رو برامون Pre-Render میکنه.

getServerSideProps
getServerSideProps


به طور کلی این تابع در سمت server اجرا میشه و هرگز روی مروگر کاربر اجرا نخواهد شد و وقتی که شما صفحه SSR رو از طریق next/link و یا next/router از سمت Client درخواست (Request) میدید، Nextjs هم میاد درخواست شما رو در قالب یک Api Request میفرسته سمت Server که شامل getServerSideProps هست . یه نکته جالب دیگه ای که لازمه بدونید اینه که Nextjs عملیات Client-bundle رو هم انجام میده به این معنی که میاد اون کدهایی که لازم نیست در سمت client باشن و bundle بشن رو حذف میکنه مثل همین تابع getServerSideProps . برای اینکه بهتر درک کنید داستان از چه قراره خوده Nextjs یه ابزار تدارک دیده که میتونین این موردی که خدمتتون عرض کردم رو از اینجا ببینید .

و این هم یه مثال دیگه از SSR برای زمانی که Request داده میشه و عملیات Pre-rendering انجام میشه

SSR at Request time
SSR at Request time


مبحث جالب دیگه از SSR هست که در واقع خاصیت Caching اون هست که میتونیم با (Cache-Control) توی header مون تعریفش کنیم و حتی با استفاده از stale-while-revalidate. میتونیم برای Revalidate اون، زمان بندی تعریف کنیم به این صورت که در تصویر پایین مشاهده میکنید.

SSR Caching
SSR Caching


SSR
SSR

درباره SSG

برای زمانی که میخواید از Static Site Generation یا همون SSG استفاده کنید، کافیه تابع getStaticProps رو توی صفحه تون export کنید و وقتی Nextjs بلافاصله ببینه تو صفحه تون از این تابع استفاده کردین فقط یکبار موقع build پروژه اون رو Pre-render میکنه برامون (بر عکس SSR که به ازای هر Request میومد برامون Pre-render رو انجام میداد. ) که به این صورت که در تصویر پایین میبینید پیاده سازی میشه

SSG
SSG



حالا فرقش با SSR توی چیه؟ ما صفحه ای رو SSR میکردیم که اطلاعاتش همش در حال بروز شدن بود و میخواستیم کاربر هر بار Request میزنه ، صفحه مون هم Pre-Render بشه و هم SEO گوگل اون هم حفظ بشه ولی توی SSG میگیم آقا ! ما نمیخوایم صفحه مون به ازای هر بار Request کاربر بخواد Pre-render انجام بده چون data مون هربار تغییری نمیکنه و یکبار هم Pre-render انجام بشه برامون کافیه و همین هم باعث میشه صفحه مون با سرعت بالاتری نمایش داده بشه که اگه گوگل ببینه سرعت صفحه بالاست ، کلی کیف میکنه و میگه درود بر شرفت ! (شوخی کردم😄 نمیگه درود به شرفت ولی خب سرعت صفحه ، فاکتور مهمیه برای گوگل ) . حالا اون یکبار Pre-render کجاست؟ اون زمانی که پروژه رو build میگیری . و اینم بهتره بدونید SEO گوگل هم برای این دوستمون هم انجام میشه .

و این هم یه مثال از SSG

SSG from CMS
SSG from CMS


یه موضوع دیگه ای که Nextjs در خصوص SSG بهش اشاره کرده اینه که میگه getStaticProps چون HTML که درست میکنه بصورت static هست به Request های ورودی مثل query parameters و HTTP headers دسترسی نداره و برای اینکه دسترسی داشته باشیم باید از Middleware استفاده کنیم .

درباره ISR

متد بعدی که میخوام خدمت شما معرفی کنم ISR یا همون Incremental Static Regeneration هست . شبیه SSG هست با این تفاوت برای build کردن کافیه بهش بگی مثلا بعد از ده ثانیه دوباره از این صفحه build بگیر به چه صورت ؟ به این صورت که در تصویر پایین مشاهده میکنید .

ISR
ISR


همونطور که مشاهده میکنید ISR تابع جدیدی نداره و همون تابع getStaticProps هست با این تفاوت که یک کلید revalidate بهش اضافه میکنید که مشخص میکنه بعد از چند ثانیه صفحه مجدد build گرفته بشه .

ISR
ISR

احتمالا توی این مثال چشمتون به getStaticPath خورده و براتون سوال شده که این چیه دیگه! ? خب شما وقتی صفحه ای دارید که از Dynamic Routes و getStaticProps استفاده میکنه ، احتیاج به این تابع داره تا path هارو بصورت static تعریف کنه و Nextjs ببینه از این تابع استفاده کردین ، تمامی path هایی که مشخص کردین رو بصورت static میاد Pre-render میکنه . و اینم یه مثال از getStaticPath

getStaticPath
getStaticPath


برای اینکه بیشتر راجع بهش بدونین میتونین از اینجا پیگیریش کنین . خب بریم سراغ ISR خودمون ،فکر کنم تا الان متوجه شدین که ISR در واقع ترکیبی از SSR و SSG هست چون داخل SSG میتونی Pre-render سمت SSR رو داشته باشید با اضافه کردن کلید revalidate اما با رنگ و لعاب SSG .


مَخلص کلام

با توجه به این مواردی که خدمتتون عرض کردم نمیتونیم به طور قطع بگیم این متد از اون یکی کامل تره و بهتره باید با توجه به نیازمون در داخل پروژه ببینیم چه متد مناسب کار ما هست ، ممکنه یه صفحه مون اصلا به SEO گوگل احتیاجی نداشته باشه میایم از CSR استفاده میکنیم ، ممکنه صفحه داشته باشیم که هر لحظه data ش update میشه مثل لیست قیمت محصولات فروشگاه و میخوایم گوگل اون رو index کنه ، پس بهتره از SSR استفاده بشه . و یا مثلا صفحه وبلاگی داریم میخوایم گوگل اونو index کنه ولی اطلاعاتش دیر به دیر update میشه، خب میایم از SSG استفاده میکنیم و یا میخوایم ترکیبی عمل کنیم یعنی صفحه مون میخوایم SSG باشه ولی بعد از یه مدت خاص Pre-render بشه اونجا هم میایم از ISR استفاده میکنیم و تمام. امیدوارم از خوندن این مقاله نهایت استفاده رو کرده باشید، روز و روزگارتون خوش.

next jspre renderssrssgcsr
دویی از خود بُرون کردم یکی دیدم دوعالم را / یکی جویم، یکی گویم، یکی دانم، یکی خوانم
شاید از این پست‌ها خوشتان بیاید