کامپایل کردن(Compiling) چیست؟
توسعه دهندگان کدهای خود را با زبانهایی مینویسند که این زبانها بیشتر مورد پسند آنهاست یا به عبارت دیگر Developer-Friendly هستند، مانند JSX، TypeScript و نسخه مدرن جاوا اسکریپت. این زبانهای برنامهنویسی علاوه بر ایجاد اعتماد در برنامهنویسان، کدهای آن ها را نیز کاربردیتر و موثرتر میکنند. اما باید به گونهای از جاوا اسکریپت تبدیل شوند که برای مرورگرها قابل فهم باشند. اینجاست که مفهوم کامپایل به میان میآید.
کامپایل به فرآیند گرفتن کد در یک زبان و تبدیل آن به زبان دیگر یا نسخه دیگری از همان زبان گفته میشود.
در Next.js، کامپایل در مرحله توسعه و همزمان با کدنویسی و به عنوان بخشی از مرحله ساخت(Build) در جهت آماده سازی کد برای تولید انجام میگیرد.
منظور از Minifying چیست؟
توسعه دهندگان کدی را مینویسند که برای فهم و خوانایی(Readability) انسان مناسب باشد. این کد ممکن است حاوی اطلاعات اضافی نیز باشد که برای اجرای کد ضروری نیستند؛ مانند: کامنتها، فاصلهها، خطوط متعدد(Multiple lines) و... .
کمینهسازی یا Minifying فرآیند حذف قالب بندی(Format) کد و کامنتهای غیرضروری بدون تغییر عملکرد کد است و هدف از آن بهبود سرعت عملکرد برنامه از طریق کاهش حجم فایل برنامه است.
در Next.js، فایلهای جاوا اسکریپت و CSS به صورت خودکار برای مرحله تولید کمینهسازی میشوند.
مفهوم Bundling چیست؟
توسعه دهندگان برنامه خود را به ماژول(Modules)ها، مولفهها و فانکشنها تقسیمبندی میکنند که میتوان از آنها برای ساخت قسمتهای بزرگتر برنامه استفاده کرد. اکسپورت(Export) و ایمپورت(Import) کردن این ماژولهای داخلی و همچنین پکیجهای third-party خارجی، یک وب پیچیده از وابستگیهای فایل ایجاد میکند.
باندلینگ یا Bundling فرآیندی است برای حل کردن وب وابستگیها(Web of dependencies) و ادغام(یا پکیج کردن) فایلها(یا ماژولها) در بسته(Bundle)های بهینهسازی شده برای مرورگر با هدف کاهش تعداد درخواست(Request)ها برای فایلها هنگام بازدید کاربر از یک صفحه وب.
تقسیم کد یا Code Splitting چیست؟
توسعهدهندگان معمولاً برنامههای خود را به چندین صفحه تقسیمبندی میکنند که از URLهای مختلف قابل دسترسی هستند. هر یک از این صفحات به یک نقطه ورود منحصر به فرد به داخل برنامه تبدیل میشود.
تقسیم کد یا Code Splitting فرآیند تقسیم باندلهای برنامه به تکههای کوچکتر مورد نیاز هر نقطه ورودی(Entry Point) است. هدف از این کار، بهبود زمان بارگذاری اولیه برنامه، تنها با بارگذاری کد مورد نیاز برای اجرای آن صفحه است.
نکست جی اس دارای پشتیبانی داخلی برای تقسیم کد است. هر فایل داخل دایرکتوری pages/ شما، به طور خودکار، در مرحله ساخت، به باندل جاوا اسکریپت خود تقسیم میشود.
به علاوه:
۱) هر کدی که بین صفحات به اشتراک گذاشته میشود نیز به باندل های دیگری تقسیم میشود تا از دانلود مجدد همان کد در نَویگِیشِن(Navigation) بیشتر جلوگیری شود.
۲) بعد از Load اولیه صفحه، Next.js میتواند شروع کند به پیش بارگذاری(Pre-loading) کد صفحات دیگری که کاربران احتمالاً به آن ها نیز مراجعه خواهند کرد.
۳) ایمپورت پویا(Dynamic Import) روش دیگری برای تقسیم بندی دستی(Manual) کدهایی است که در ابتدا بارگذاری شدهاند.
مفهوم دو اصطلاح زمان ساخت(Build Time) و زمان اجرا (Runtime):
زمان ساخت(یا مرحله ساخت) نامی است که به یکسری مراحل داده میشود و در این مراحل، کد برنامه برای تولید آمادهسازی میشود.
زمانی که برنامه خود را میسازید، Next.js کد شما را به فایلهای بهینهسازی شده تولید یا Production-Optimized تبدیل میکند که آماده قرار گرفتن و استقرار در سرورها و استفاده کاربران هستند. این فایلها عبارتند از:
۱) فایلهای HTML برای صفحات ایجاد شده به صورت استاتیک یا ایستا
۲) کدهای جاوا اسکریپتی برای رندر شدن صفحات در سرور
۳) کدهای جاوا اسکریپتی برای ساخت صفحات تعاملی در قسمت مشتریان(Client)
۴) فایلهای CSS
زمان اجرا (یا زمان درخواست) به مدت زمانی اشاره دارد که برنامه شما در پاسخ به درخواست کاربر اجرا میشود(پس از اینکه برنامه شما ساخته و اجرا میشود).
تا اینجا با مفاهیم و ویژگیهای Next.js آشنا شدید. حال در ادامه بیایید با هم در مورد Client، Server و Rendering بیشتر صحبت کنیم.
مشتری و سرور(Client and Server):
مشتری: در زمینه برنامههای تحت وب، Client به مرورگری گفته میشود که بر روی دستگاه کاربران قرار دارد و درخواستی را برای کد برنامه به سرور ارسال میکند. سپس پاسخی را که از سرور دریافت میکند به رابطی(Interface) تبدیل میکند که کاربر بتواند با آن تعامل داشته باشد.
سرور: به رایانهای در یک مرکز داده(Data Centre) اشاره دارد که کد برنامه شما را ذخیره میکند، درخواستهای مشتری را دریافت میکند، مقداری محاسبات را انجام میدهد و پاسخ مناسب را ارسال میکند.
منظور از Rendering چیست؟
در اینجا به فرآیند تبدیل کدهای نوشته شده توسط برنامهنویسان در React به اشکال قابل نمایش در قالب رابط کاربری HTML، Rendering گفته میشود. فرآیند رندر کردن میتواند بر روی Server یا Client انجام شده و همچنین میتواند در زمان ساخت(Build Time)، در هر درخواست(Request) و یا در زمان اجرا(Runtime) صورت گیرد. با Next.js سه روش برای رندر در دسترس است: رندر سمت سرور(Server-Side Rendering)، تولید سایت استاتیک یا ایستا(Static Site Generation) و رندر سمت کلاینت(Client-Side Rendering).
مفهوم پیش رندر یا Pre-Rendering چیست؟
رندر سمت سرور و تولید سایت ایستا به عنوان پیش رندر نیز شناخته میشود، زیرا فچ کردن(Fetching) دادههای خارجی و تبدیل اجزای React به HTML، قبل از ارسال نتیجه به Client اتفاق میافتد.
تفاوت بین Pre-Rendering و Client-Side Rendering چیست؟
در یک اپلیکیشن استاندارد ری اکت، مرورگر یک پوسته HTML خالی از سرور به همراه دستورالعملهای جاوا اسکریپت برای ساخت رابط کاربری دریافت میکند. به این عملکرد، رندر سمت کلاینت گفته میشود، زیرا رندر اولیه در کامپیوتر کاربر صورت میگیرد.
نکته: میتوانید با فچ دادهها با هوکهایی مانند useEffect() یا useSWR، از رندر سمت کلاینت برای کامپوننتهای بخصوصی در برنامه Next.js خود بهره بگیرید.
در مقابل، Next.js به طور پیشفرض هر صفحه را پیش رندر میکند. پیش رندر به این معناست که: به جای اینکه همه کارها توسط جاوا اسکریپت در کامپیوتر کاربر انجام شود، HTML از پیش بر روی سرور ساخته و تولید یا بهتر است بگوییم Generate میشود. در عمل این بدان معناست که برای یک برنامه کاملاً رندر شده توسط مشتری(منظور این است که اگر برنامهای به صورت کامل توسط Client رندر شود)، کاربر یک صفحه خالی را در حین انجام رندر میبیند. در مقایسه با یک برنامه از پیش رندر شده که در آن کاربر HTML ساختهشده را میبیند:
حال بیایید در مورد دو نوع مختلف پیش رندر با هم صحبت کنیم:
رندر سمت سرور یا Server-Side Rendering:
با رندر سمت سرور، HTML آن صفحه برای هر درخواست در سرور ایجاد میشود. HTMLهای ایجاد شده، دادههای JSON و جاوا اسکریپت تولیدشده برای تعاملی کردن صفحه برای کلاینت ارسال میشوند.
در سمت کلاینت، HTML برای نمایش یک صفحه سریع غیرتعاملی(non-interactive) استفاده میشود؛ در حالی که React از دادههای JSON و دستورالعملهای جاوا اسکریپت برای تعاملی کردن کامپوننتها استفاده میکند (به عنوان مثال، پیوست کردن کنترل کنندههای رویداد به یک دکمه یا به انگلیسی: attaching event handlers to a button). به این فرآیند hydration گفته میشود.
در Next.js، میتوانید صفحاتی که قرار است در سمت سرور رندر شوند را با استفاده از getServerSideProps انتخاب کنید.
نکته: React 18 و Next 12، یک نسخه آلفا از کامپوننت سرور React معرفی میکنند. کامپوننتهای سرور به طور کامل بر روی سرور رندر میشوند و برای رندر نیازی به کمک جاوا اسکریپت سمت کلاینت ندارند. علاوه بر این کامپوننتهای سرور به توسعه دهندگان اجازه میدهند تا مقداری کد را روی سرور نگه دارند و فقط نتیجه آن کد را برای کلاینت ارسال کنند. این باعث کاهش سایز باندل(به انگلیسی Bundle، در بحث برنامهنویسی به مجموعهای از مقادیر و برنامههای نرم افزاری مرتبط به یکدیگر که همگی با هم یک پکیج را تشکیل میدهند باندل گفته میشود)، نرم افزاری ارسال شده به کلاینت و بهبود عملکرد رندر سمت مشتری میشود.
تولید سایت استاتیک یا ایستا(Static Site Generation):
با تولید یک سایت ایستا، HTML بر روی سرور ایجاد میشود؛ اما برخلاف رندر سمت سرور، هیچ سروری در زمان اجرا وجود ندارد. در عوض محتوا یکبار در زمان ساخت(هنگام استقرار یا همان deploy برنامه)، تواید شده و HTML در یک CDN (یا شبکه تحویل محتوا، به گروهی از سرورهای توزیع شده در مناطق جغرافیایی مختلف اشاره دارد که برای ارائه سریع محتوای اینترنتی با هم کار میکنند، در ادامه به توضیح بیشتر آن خواهیم پرداخت) ذخیره میشود و برای هر درخواست دوباره مورد استفاده قرار میگیرد.
در Next.js، میتوانید با استفاده از getStaticProps، صفحات را بصورت استاتیک تولید کنید.
نکته: Next.js ویژگی به نام بازسازی استاتیکی افزایشی(Incremental Static Regeneration) را در اختیار شما قرار میدهد که با آن میتوانید بدون نیاز به بازسازی(rebuild) کل سایت، صفحات جدید ایجاد کنید و یا صفحات قبلی را بروزرسانی کنید.
زیبایی Next.js در این است که میتوانید مناسبترین روش رندرینگ را برای موارد استفاده خود به صورت صفحه به صفحه انتخاب کنید؛ خواه این روش تولید سایت استاتیک، رندر سمت سرور یا رندر سمت کلاینت باشد!
منظور از Network یا شبکه چیست؟
دانستن اینکه کد شما در کجا ذخیره شده و پس از استقرار قرار است در شبکه اجرا شود، به نوبه خود حائز اهمیت است. میتوان شبکه را اینگونه تعریف کرد: رایانههای(یا سرورهای) متصل به یکدیگر که قادر به اشتراکگذاری منابع هستند. در مورد یک برنامه Next.js، کد برنامه شما میتواند در سرورهای مبدأ، شبکههای تحویل محتوا یا همان CDN و Edge توزیع شود. حال بیایید باهم ببینیم هر یک از آنها چیستند:
۱) سرورهای مبدأ یا Origin Servers:
همانطور که قبلاً گفتیم، سرور به رایانه اصلی اطلاق میشود که نسخه اصلی کد برنامه شما بر روی آن ذخیره و اجرا میشود. از عبارت مبدأ یا Origin به این دلیل برای این سرورها استفاده میشود که آن را از مکانهای دیگری که میتوان کد برنامه را بر روی آنها ذخیره نمود(مانند سرورهای CDN و Edge)، متمایز کرد. هنگامی که یک سرور مبدأ درخواستی را دریافت میکند، قبل از ارسال پاسخ، قسمتی از محاسبات را انجام میدهد. نتیجه این کار محاسباتی را میتوان به CDN منتقل کرد.
۲) شبکه تحویل محتوا یا CDN(Content Delivery Network):
سرورهای CDN، محتوای ثابت(مانند HTML و فایل های تصویری) را در مکانهای مختلف در سرتاسر جهان ذخیره میکنند و بین کلاینت و سرور اصلی قرار میگیرند. هنگامی که یک درخواست جدید وارد میشود، نزدیکترین مکان CDN به کاربر میتواند با نتیجه ذخیره شده(Cached result) پاسخ(Respond) دهد.
این باعث کاهش بار روی سرور مبدأ میشود زیرا دیگر نیازی نیست که محاسبات در هر درخواست انجام شوند. همچنین این کار را برای کاربر سریع تر میکند؛ زیرا پاسخ از موقعیت جغرافیایی نزدیک تر به آنها میآید.
در Next.js، از آنجایی که میتوان پیش رندر را زودتر از موعد انجام داد، CDNها برای ذخیره نتیجه استاتیک(Static result) کار مناسب هستند؛ به زبان سادهتر، فرآیند تحویل محتوا را سریعتر میکند.
۳) سرور Edge:
عبارت The Edge، یک مفهوم تعمیمیافته برای حاشیه(Fringe) یا همان لبه شبکه است که نزدیکترین بخش به کاربر است. CDNها را میتوان بخشی از Edge در نظر گرفت؛ زیرا محتوای ثابت را در حاشیه(لبه) شبکه ذخیره میکند. همانند CDNها، سرورهای Edge نیز در چندین مکان در سراسر جهان توزیع میشوند. اما بر خلاف CDNها که محتوای ثابت(محتوای استاتیک) را ذخیره میکنند، برخی از سرورهای Edge میتوانند قسمتهای کوچکی از کد را اجرا کنند. این بدان معناست که هم Cache کردن و هم اجرای کد را میتوان در Edgeای که نزدیک به کاربر است انجام داد. با انتقال برخی از فرآیندها و محاسباتی که پیشتر در سمت سرور یا کلاینت انجام میشد به Edge، میتوانید برنامه خود را کارآمدتر کنید؛ زیرا مقدار کد ارسالی به کلاینت را کاهش میدهد و نیازی نیست که بخشی از درخواست کاربر دیگر نیاز نیست که به سرور مبدأ جهت انجام محاسبات بازگردانده شود؛ بنابراین میتوانیم شاهد کاهش چشمگیر تأخیر در پاسخگویی باشیم.
در Next.js میتوانید کد را با کمک یک میان افزار یا Middleware(میان افزار، نرم افزار و سرویسهای ابری است که خدمات و قابلیتهای مشترکی را به برنامهها ارائه میکند و به توسعهدهندگان و اپراتورها کمک میکند تا برنامهها را با کارایی بیشتری بسازند و بکارگیری کنند. بطورکلی میان افزار مانند یک چنل ارتباطی میان برنامهها، دادهها و کاربران عمل میکند) در Edge و بزودی با React Server Component اجرا کنید.
شرکت توسعه نرمافزاری پیشگامان لوتوس:
ما مفتخریم که در پیشگامان لوتوس با تیمی مجرب خدمات خود را در زمینههای طراحی وبسایت، اپلیکیشن، واقعیت افزوده و... با جدیدترین تکنولوژیهای روز دنیا از جمله React، Next.js،React Native و... ارائه میدهیم.