وقتی اپلیکیشنهای ریکت میسازید، احتمالاً شنیدهاید که ریکت رابط کاربری را به صورت یک "درخت" در نظر میگیرد. اما دقیقاً منظور از این حرف چیست؟ و چرا باید برایتان مهم باشد؟
درک اینکه ریکت چگونه اپلیکیشن شما را به صورت یک درخت مدلسازی میکند، میتواند تأثیر زیادی روی شیوهٔ نوشتن کامپوننتها، دیباگ کردن مشکلات رندر، و حتی بهینهسازی عملکرد داشته باشد. در این مقاله، به بررسی درخت رندر (Render Tree) و درخت وابستگی ماژولها (Module Dependency Tree) در ریکت میپردازیم — و اینکه این ساختارها چطور روی اپلیکیشن شما تأثیر میگذارند.

در توسعهٔ مدرن فرانتاند، فکر کردن به ساختارها به صورت "درخت" فقط یک استعاره نیست — بلکه یک اصل کلیدی است. بسیاری از کتابخانههای UI، از جمله ریاکت، رابط کاربری را به شکل درختی از کامپوننتها مدل میکنند. این ساختار سلسلهمراتبی به ما کمک میکند روابط بین بخشهای مختلف رابط کاربری را بهتر بفهمیم.
هر کامپوننت در اپلیکیشن شما به یک گره (Node) در درخت تبدیل میشود. وقتی کامپوننتها داخل هم قرار میگیرند، رابطهٔ پدر-فرزندی ایجاد میشود. این روابط برای ریاکت هنگام رندر و محاسبهٔ تغییرات، کاملاً حیاتی هستند.
این نوع مدلسازی فقط مختص ریاکت نیست. مرورگرها از درختها برای مدلسازی HTML (بهصورت DOM) و CSS (بهصورت CSSOM) استفاده میکنند. پلتفرمهای موبایل هم سلسلهمراتب ویوهای خود را با درختها نمایش میدهند.
در درخت رندر:
هر گره یک کامپوننت ریکتی است.
هر شاخه یک دستور render است.
گره ریشه معمولا فایلAppاست — همان فایلی که اپلیکیشن از آن شروع میشود.

زمانی که یک اپلیکیشن ریکت را رندر میکنید، ریکت یک درخت رندر (Render Tree) میسازد. این درخت فقط شامل کامپوننتهای ریکت است — نه تگهای HTML و نه عناصر UI مربوط به پلتفرم مقصد.
بیایید به یک اپلیکیشن ساده نگاه کنیم:
import FancyText from './FancyText';
import InspirationGenerator from './InspirationGenerator';
import Copyright from './Copyright';
export default function App() {
return (
<>
<FancyText title text="Get Inspired App" />
<InspirationGenerator>
<Copyright year={2004} />
</InspirationGenerator>
</>
);
}
در اینجا ریکت یک درخت رندر میسازد که:
App گره ریشه است، چون ریشهٔ ساختار کامپوننتهای ماست.
FancyTextوInspirationGeneratorفرزندان کامپوننت Appهستند و Copyrightیک فرزند از InspirationGeneratorاست.
نکتهٔ مهم این است که این ساختار فقط شامل کامپوننتهای ریکت است و کاری به عناصر HTML یا UIهای خاص پلتفرم ندارد، چون ریکت وابسته به پلتفرم خاصی نیست. چه به وب رندر شود، چه موبایل یا دسکتاپ، برای ریکت فرقی نمیکند.
درخت رندر مربوط به یک بار رندر خاص است. یعنی ساختار کامپوننتها در یک وضعیت خاص از اپلیکیشن را نشان میدهد.
اما ریکت از رندر شرطی (Conditional Rendering) پشتیبانی میکند. یعنی بسته به مقدار props یا state، ممکن است کامپوننتها فرزندان مختلفی رندر کنند. در نتیجه، درخت رندر ممکن است در هر بار رندر متفاوت باشد.
برای مثال، اگر مقدار inspiration.type تعیین کند که <FancyText> یا <Color> رندر شود، درخت رندر در هر حالت متفاوت خواهد بود.
import FancyText from './FancyText';
import Color from './Color';
export default function InspirationRenderer({ inspiration }) {
if (inspiration.type === 'text') {
return <FancyText text={inspiration.value} />;
} else if (inspiration.type === 'color') {
return <Color hex={inspiration.value} />;
} else {
return null;
}
}با وجود این تغییرات، درختهای رندر بسیار مفیدند برای:
شناسایی کامپوننتهای سطح بالا (نزدیک به ریشه) که روی تمام کامپوننتهای زیرین اثر دارند.
پیدا کردن کامپوننتهای برگ (leaf components) که فرزندی ندارند و معمولاً زیاد باز-رندر میشوند.
شناسایی این دستهها برای دیباگ عملکرد و درک جریان داده در اپلیکیشن مفید است.
علاوه بر ساختار کامپوننتها، ساختار مهم دیگری هم وجود دارد: درخت وابستگی ماژول (Module Dependency Tree). با گسترش اپلیکیشن، کدها را در فایلهای جداگانه مینویسیم — ماژولهایی که کامپوننت، تابع یا ثابتها را صادر میکنند. هر بار که یک فایل از فایل دیگر چیزی import میکند، یک ارتباط جدید در این درخت ساخته میشود.
در درخت وابستگی ماژول:
هر گره یک فایل جاوااسکریپت (ماژول) است.
هر شاخه یک دستور import است.
گره ریشه فایل entrypoint اپلیکیشن است — همان فایلی که اپلیکیشن از آن شروع میشود.
مقایسه با درخت رندر:
برای مثال، در درخت رندر، کامپوننت Copyright زیر InspirationGenerator قرار دارد چون به عنوان children به آن داده شده. اما در درخت وابستگی، فایل Copyright.js زیر App.js قرار دارد، چون از آنجا import شده است.
در مرحلهٔ production، ابزارهای باندلینگ (مانند Webpack، Vite یا Parcel) از درخت وابستگی ماژول استفاده میکنند تا مشخص کنند کدام ماژولها باید در باندل نهایی قرار بگیرند.
زمان دانلود بیشتر
زمان تجزیه و اجرای بیشتر
تأخیر در اولین نمایش UI
ماژولهای غیرضروری را شناسایی کنید
فرصتهای کد اسپلینتینگ (Code Splitting) را پیدا کنید
عملکرد اپلیکیشن را بهبود دهید و تجربه کاربر را ارتقا دهید
بیایید مروری داشته باشیم:
ریکت UI شما را به شکل درختی از کامپوننتها مدلسازی میکند.
درخت رندر ساختار تو در توی کامپوننتها را در یک رندر خاص نمایش میدهد.
با رندر شرطی، درخت رندر میتواند بین دفعات مختلف تغییر کند.
شناخت کامپوننتهای سطح بالا و کامپوننتهای برگ برای دیباگ و بهینهسازی عملکرد مفید است.
درخت وابستگی ماژول نشان میدهد که فایلهای جاوااسکریپت شما چطور به هم وابسته هستند.
ابزارهای باندلینگ از این درخت استفاده میکنند تا فقط کدهای مورد نیاز را در باندل قرار دهند.
درک اینکه ریکت چطور از ساختارهای درختی برای مدلسازی رابط کاربری و ماژولها استفاده میکند، فقط یک موضوع نظری نیست — بلکه کاملاً کاربردی است. چه بخواهید مشکل عملکردی را حل کنید، چه بخواهید کد را بهینه کنید، این درختها نقشهٔ ذهنی بسیار مفیدی برای شما خواهند بود.اگه این مقاله برات مفید بود، خوشحال میشم اونو به اشتراک بذاری یا نظرت رو بنویسی.
