ویرگول
ورودثبت نام
عباس وزیری
عباس وزیریسلام عباسم 19 سالمه. دوسالی میشه فرانت کار میکنم و یه ادم تشنه به دیباگ کردن هستم(:
عباس وزیری
عباس وزیری
خواندن ۷ دقیقه·۱۰ ماه پیش

چگونه React در پشت صحنه کار می‌کند؟

سلام!
من عباس وزیری هستم و این اولین پستم در ویرگول است. خوشحال می‌شوم نظرتان را درباره این مقاله بدانم. مرسی که وقت می‌گذارید! 😊

خب الان میخایم بریم راجب این صحبت کنیم که ریکت در پشت صحنه چجوری صفحه مارو رو رندر میکنه.

نکته:‌ اولین نکته همین اول اینه که ما میخایم رندر شدن صفحه رو بگیم نمیخایم راجب UI چجوری نمایش داده میشه یا نمایش UI صحبت کنیم. چون خیلی از افراد این بحث رندرینگ رو میان و با نمایش UI یکی میکنند یا بهتر بگیم گیج میشن.
حالا میایم میگیم فرق این دو چیه؟ یکی اینکه رندرینگ و دوم این نمایش UI
رندرینگ میاد میگه اقا براساس یک props یا state که داخل اپمون تغییر کرده بیا VDOM رو تغییر بده و محاسبه کن که UI چجوری باید باشه.
اما نمایش UI یعنی بیا تغییرات رو داخل DOM بزار و نمایش بده.
بریم سراغ مراحل رندرینگمون

بیایم شروع کنیم و بگیم که اصلا در چه مواقعی ریکت قرار هست برای ما صفحه رو رندر کنه. کلا ریکت در دو حالت هستش که میاد صفحه مارو رندر میکنه:

1. وقتی که کل اپ برای بار اول میخاد استارت بشه یا به اصطلاح (initial rendering)
2. وقتی که یک state یا props داخل یک یا چند کامپوننتمون تغییر کنه. (re-render)

مراحل رندرینگ در ریکت

  1. مرحله اول مرحله ای است که ما در ریکت شروع میکنیم به ساختن کامپوننت هامون یا کامپوننتی داریم و state یا props داخلش عوض میشه که باعث راه انداختن پروسه رندر شدن میشه.
  2. در مرحله اول وقتی ما یک کامپوننت میسازیم برای مثال یک کامپوننت با jsx ریکت این رو میزاره داخل Vritual Dom Tree خب داخل این درخت ما هرکدوم از کامپوننت هامون میشن یدونه node داخل این Virtual Dom که هرکدومشون یک آبجکت هستش.
    خب حالا به احتمال زیاد سوالتون اینه که اصن Vritual Dom چیه؟
    Virtual Dom یا به اختصار VDOM (از اینجا به بعد اینو میگم) یک نسخه‌ی سبک و ایده‌آل از DOM اصلی است که در مموری مرورگر ذخیره می‌شود. این نسخه به کمک کتابخانه‌هایی مثل ReactDOM با DOM واقعی سینک می‌شود تا رابط کاربری (UI) بهینه‌تر و سریع‌تر به‌روزرسانی شود. چیزی که الان بنظرم خیلی مفیده براتون چون برای خوده من بوده که چجوری اصن قراره که این اطلاعات ذخیره بشن داخل VDOM یا اصن کد داخل VDOM چه شکلی هستش. یک نمونه کد رو ببینیم:‌
<div> <h1 className=&quottitle&quot>Want to learn about Virtual DOM?</h1> <div className=&quotbutton-container&quot> <Button title=&quotYes&quot /> <Button title=&quotNo&quot /> </div> </div>

بعد میاد داخل VDOM به این صورت دخیره میشه:

{ type: 'div', key: null, ref: null, props: { children: [ { type: 'h1', key: null, ref: null, props: { className: 'title', children: 'Want to learn about Virtual DOM?' } }, { type: 'div', key: null, ref: null, props: { className: 'button-container', children: [ { type: Button(), props: { title: 'Yes' } }, { type: Button(), props: { title: 'No' } } ] } } ] } }

ریکت دوتا نسخه VDOM درست میکنه که این میره توی مموری مرورگر ذخیره میشه:

  • نسخه ای که نمایش میده وضعیت فعلی UI و State ها هست.
  • نسخه ای که بعد از هر تغییری ایجاد میشود.

مهم‌ترین نکته اینه که ریکت از Key برای المنت ها استفاده می‌کنه. Key به ریکت کمک می‌کنه که تغییرات رو بهتر مدیریت کنه. به جای اینکه کل UI رو دوباره رندر کنه، ریکت نسخه فعلی VDOM رو با نسخه جدیدش مقایسه می‌کنه (Diffing Algorithm). بر اساس این مقایسه، فقط تغییرات لازم روی DOM واقعی اعمال می‌شه.

اینجا ما میایم میگیم ریکت یک نسخه از VDOM رو نگه میداره داخل مموری حالا این مموری کجاست؟
در مورد اینکه این VDOM کجا نگه‌داری می‌شه:
VDOM یک آبجکت جاوااسکریپتیه. این آبجکت در Heap، که بخشی از حافظه مرورگر (RAM) و JavaScript Runtime هست، ذخیره می‌شه. مرورگر محیطی به نام Runtime برای اجرای جاوااسکریپت فراهم می‌کنه که شامل دو بخش اصلیه:

  • heap: جایی که داده های داینامیک (مثل آبجکت ها) ذخیره میشن
  • call stack: جایی که توابع برای اجرا وارد میشن

بنابراین، VDOM به‌عنوان یک آبجکت، در Heap قرار می‌گیره.

نکته: رندرینگ کامپوننت ها در اپ ریکتی همیشه باعث میشه که فرزندان اون کامپوننت هم ری رندر بشن. اصلا مهم نیست یک props باشد یا کل کامپوننت در هر صورت اگر چیزی تغییر کند در کامپوننت فررزند هم رندرینگ داریم.
سوالی که بازم پیش میاد اینه: خب همونطوری که تو گفتی هر وقت کامپوننت بسازیم یا کاری کنیم که state داخل اپمون تغییری بکنه باید از دوباره VDOM درست بشه یعنی هر بار یدونه جدید؟ همیشه رندر کنیم کامپوننت فرزندان رو چون parent تغییر داشته؟ یعنی ریکت اینجوریع!؟؟ نه نه نه اینجاست که Reconciliation میاد وارد داستان مراحل رندرینگمون میشه



۳. مرحله بعدی که میتونیم بگیم مرحله سوم Reconciliation (همگام سازی یا میتونیم بگیم مقایسه تغییرات)

مرحله‌ی Reconciliation در React، پروسه‌ای است که طی آن React تصمیم می‌گیرد کدام DOM element باید تغییر کند تا با آخرین تغییرات state یا props در اپلیکیشن هماهنگ شود.

در این مرحله:

  • ریکت ابتدا VDOM جدید را با نسخه قبلی مقایسه میکند ( فرایندی به نام diffing)
  • تنها تفاوت‌ها یا تغییرات شناسایی‌شده جدید به DOM واقعی اعمال می‌شود.

چرا این مهم است؟

  • به‌جای به‌روزرسانی کل DOM (که زمان‌بر و ناکارآمد است)، فقط بخش‌هایی که تغییر کرده‌اند به‌روزرسانی می‌شوند.
  • این کار باعث بهبود عملکرد و کاهش زمان رندر می‌شود.

وقتی درباره همگام‌سازی (Reconciliation) صحبت می‌کنیم، ابزار مهم و قدرتمندی که React استفاده می‌کند، Fiber است. Fiber یکی از اجزای اصلی React است که فرآیند Reconciliation را بهینه می‌کند.

نکته راجبه reconcilar:
میتونیم بگیم این reconcilar قلب ریکت هستش یا میتونیم بگیم موتور ریکت هستش برای چی برای اینکه اگر ما بخایم DOM رو هربار عوض کنیم به شدت برنامه کند میشع و اصلا خوب نیست این reconcilar هستش که نمیزاره ما هیچ وقت به DOM مستقیما دست بزنیم.

۴. مرحله بعدی که میتونیم بهش بگیم درخت فایبر یا (Fiber Tree)

Fiber معماری داخلی React برای مدیریت Reconciliation است. این سیستم به React کمک می‌کند که فرآیندهای پیچیده را بهتر مدیریت کند و تجربه کاربری روان‌تری ارائه دهد. برای هر کامپوننت و DOM المنت یدونه fiber هست.

ویژگی‌های Fiber Tree:

  • مدیریت فرآیندهای سنگین: Fiber می‌تواند کارهای سنگین را به بخش‌های کوچک‌تر تقسیم کند.
    وظایف را اولویت‌بندی کرده و در صورت نیاز متوقف یا ادامه دهد.
  • چیزی که این درخت فایبر رو خاص میکنه اینه که برخلاف ریکت المنت داخل VDOM این Fibers از دوباره تولید نمیشن برای هر رندر پس Fiber Tree هیچ وقت شکسته نمیشه یا پاک نمیشع.
  • بهینه‌سازی رندر غیرهمزمان (Asynchronous Rendering):رندرهای سنگین مسدود نمی‌شوند و سایر کارها مانند تعاملات کاربر بدون وقفه ادامه پیدا می‌کنند.
  • ساختار داخلی انعطاف‌پذیر: هر گره (Node) در درخت فیبر نماینده یک کامپوننت یا DOM element است.
    اولین فرزند هر گره به والد خود متصل است و فرزندان دیگر به صورت لیست پیوندی (Linked List) به یکدیگر متصل هستند.

اهمیت Fiber:

  • فرآیند رندر را به بخش‌های کوچک‌تر تقسیم کند.
  • ویژگی‌های پیشرفته‌ای مانند Suspense و Transition را فعال کند.
  • رندر غیرهمزمان انجام دهد تا UI روان و بدون اختلال بماند.
react rendering steps
react rendering steps


۵. مرحله اخر یعنی مرحله commit phase و browser paint

همونجوری که داخل عکسی که گزاشتم میتونید ببینید در render phase [2] ما میایم یه لیست میگیریم از DOM updates ریکت نمیاد DOM رو دست بزنه ریکت فقط رندر میکنه. تا اینجا کار نمیدونه کجا باید نتیجه رندر بره.
در اینجا یعنی Commit Phase یک کتابخونه دگه ای وجود داره که برای Commit هستش که بهشون میگن renderers:
برای مثال:

  • React DOM
  • React native
  • Remotion etc

این ها رندر نمیکنن اینها commit میکنن نتیجه render phase رو.

  • در ریکت، تغییرات در DOM شامل افزودن، حذف و به‌روزرسانی عناصر است. لیستی از این تغییرات آماده می‌شود و در نهایت روی DOM اعمال می‌شود.
  • کامیت کردن (commit) به‌صورت همزمان (Synchronous) انجام می‌شود، یعنی تمام تغییرات در یک مرحله روی DOM اعمال می‌شوند و نمی‌توان این فرآیند را متوقف کرد. این کار باعث می‌شود که رابط کاربری همیشه منسجم و هماهنگ با وضعیت (state) باشد و هیچ تغییری به‌صورت ناقص نمایش داده نشود.
  • پس از پایان فاز commit، درخت فیبر (Fiber Tree) که در حال پردازش بود، تبدیل به درخت اصلی می‌شود و در رندر بعدی از آن استفاده خواهد شد.

بعد از این مرورگر میاد به اصطلاح paint میکنه تغییرات رو داخل صفحه مون.


امیدوارم این مقاله به درک بهتری از نحوه کار React کمک کرده باشد. اگر سوال یا نظری دارید، خوشحال می‌شوم آن را بشنوم! 😊


react
۰
۰
عباس وزیری
عباس وزیری
سلام عباسم 19 سالمه. دوسالی میشه فرانت کار میکنم و یه ادم تشنه به دیباگ کردن هستم(:
شاید از این پست‌ها خوشتان بیاید