diff --git a/src/guide/extras/rendering-mechanism.md b/src/guide/extras/rendering-mechanism.md index 018e2bfd..e845a1f8 100644 --- a/src/guide/extras/rendering-mechanism.md +++ b/src/guide/extras/rendering-mechanism.md @@ -4,15 +4,15 @@ outline: deep # مکانیزم رندرینگ | Rendering Mechanism {#rendering-mechanism} -Vue چگونه یک تمپلیت را می‌گیرد و آن را به نودهای DOM واقعی تبدیل می‌کند؟ Vue چگونه این نودهای DOM را به طور کارآمد به‌روزرسانی می‌کند؟ در اینجا سعی می‌کنیم با برسی مکانیزم رندرینگ داخلی Vue، پاسخی برای این سوالات پیدا کنیم. +Vue چگونه یک تمپلیت را گرفته و آن را به نودهای DOM واقعی تبدیل می‌کند؟ Vue چگونه این نودهای DOM را به طور کارآمد به‌روزرسانی می‌کند؟ در اینجا سعی می‌کنیم با برسی مکانیزم رندرینگ داخلی Vue، پاسخی برای این سوالات پیدا کنیم. ## DOM مجازی | Virtual DOM {#virtual-dom} احتمالا عبارت "virtual DOM" را شنیده‌اید که سیستم رندرینگ Vue بر پایه آن است. -virtual DOM یا VDOM مفهومی برنامه‌نویسی است که در آن نمایش ایده‌آل یا "مجازی" رابط کاربری در حافظه نگهداری می‌شود و با DOM "واقعی" همگام‌سازی می‌شود. این مفهوم توسط [React](https://reactjs.org/) پایه‌گذاری شده و در بسیاری از فریم‌ورک‌های دیگر از جمله Vue با نحوه پیاده‌سازی متفاوت بکار گرفته شده است. +virtual DOM یا VDOM مفهومی برنامه‌نویسی است که در آن نمایش ایده‌آل یا "مجازی" رابط کاربری در حافظه نگهداری می‌شود و با DOM "واقعی" همگام‌سازی می‌شود. این مفهوم توسط [React](https://reactjs.org/) پایه‌گذاری شده و در بسیاری از فریم‌ورک‌های دیگر از جمله Vue، با پیاده‌سازی متفاوت، بکار گرفته شده است. -virtual DOM بیشتر از یک پَتِرن برای یک فناوری خاص است، بنابراین پیاده‌سازی رسمی واحدی برای آن وجود ندارد. می‌توانیم این ایده را با یک مثال ساده توضیح دهیم: +virtual DOM بیشتر از آنکه یک پَتِرن باشد، یک فناوری خاص محسوب می شود، بنابراین پیاده‌سازی رسمی و یکتایی برای آن وجود ندارد. می‌توانیم این ایده را با یک مثال ساده توضیح دهیم: ```js const vnode = { @@ -26,23 +26,24 @@ const vnode = { } ``` -در اینجا، `vnode` یک آبجکت ساده جاوااسکریپت (یک "virtual node") که نمایانگر یک عنصر `
` است. این شامل تمام اطلاعاتی است که برای ایجاد عنصر واقعی نیاز داریم. همچنین حاوی vnode های بیشتری است که آن را ریشه درخت DOM مجازی می‌کند. +در اینجا، `vnode` یک آبجکت ساده جاوااسکریپت (یک "virtual node") بوده که نمایانگر یک عنصر `
` است. این vnode شامل تمام اطلاعاتی است که برای ایجاد عنصر واقعی نیاز داریم. این آبجکت حاوی vnode های بیشتری به عنوان فرزند است، به همین خاطر به عنوان ریشه درخت DOM مجازی این vnode ها، در نظر گرفته می شود. -یک runtime renderer (رندرر رانتایم) می‌تواند یک درخت virtual DOM را پیمایش کند و یک درخت DOM واقعی از آن بسازد. به این فرایند **mount** گفته می‌شود. +یک runtime renderer (رندرر رانتایم) می‌تواند یک درخت virtual DOM را پیمایش کرده و یک درخت DOM واقعی از آن بسازد. به این فرایند **mount** گفته می‌شود. -اگر دو نسخه مختلف از درخت virtual DOM داشته باشیم، رندرر می‌تواند دو درخت را پیمایش و مقایسه کند تا تفاوت‌ها را مشخص کند و آن تغییرات را بر روی DOM واقعی اعمال کند. به این فرایند **patch** گفته می‌شود که به آن "diffing" یا "reconciliation" هم گفته می‌شود. +اگر دو نسخه مختلف از درخت virtual DOM داشته باشیم، رندرر می‌تواند دو درخت را پیمایش و مقایسه کند تا تفاوت‌ها را مشخص و بر روی DOM واقعی اعمال کند. به این فرایند **patch** گفته می‌شود که همچنین با "diffing" یا "reconciliation" نیز شناخته می‌شود. -دستاورد اصلی virtual DOM این است که به توسعه‌دهنده امکان می‌دهد تا به صورت اختیاری و از طریق کدهایی که به راحتی قابل فهم و تعمیم‌پذیر هستند، ساختارهای UI مورد نیاز خود را تعریف کند، در حالی که اعمال مستقیم بر روی DOM و تعامل با DOM به عهده رندرر (Renderer) باشد. + +دستاورد اصلی virtual DOM این است که به توسعه‌دهنده این امکان را می‌دهد تا به صورت اختیاری و از طریق کدهایی که به راحتی قابل فهم و تعمیم‌پذیر هستند، ساختارهای UI مورد نیاز خود را تعریف کند، در حالی که تغییر مستقیم بر روی DOM و تعامل با آن به عهده رندرر (Renderer) باشد. ## رَوند رندرینگ | Render Pipeline {#render-pipeline} -بطور کلی، این اتفاقات هنگام mount یک کامپوننت Vue رخ می‌دهد: +بطور کلی، اتفاقات زیر هنگام mount یک کامپوننت Vue رخ می‌دهد: -1. **Compile**: تمپلیت‌های Vue به **render functions** کامپایل می‌شوند: یعنی توابعی که درختان virtual DOM را برمی‌گردانند. این مرحله می‌تواند یا از پیش در build step انجام شود یا توسط کامپایلرِ رانتایم به صورت بی‌درنگ در مرورگر انجام شود. +1. **Compile**: تمپلیت‌های Vue به **render functions** کامپایل می‌شوند: یعنی توابعی که درختان virtual DOM را برمی‌گردانند. این مرحله می‌تواند یا از پیش در build step انجام شود یا توسط کامپایلرِ رانتایم به صورت لحظه ای (on-the-fly) در مرورگر انجام شود. -2. **Mount**: رندرر رانتایم render function ها را فراخوانی می‌کند، درخت virtual DOM برگردانده شده را پیمایش می‌کند و بر اساس آن نودهای DOM واقعی ایجاد می‌کند. این مرحله به عنوان [reactive effect](./reactivity-in-depth) انجام می‌شود، بنابراین تمام وابستگی‌های reactive که در طول mount استفاده شده‌اند را پیگیری می‌کند. +2. **Mount**: رندرر رانتایم render function ها را فراخوانی کرده، خروجی آنها، یعنی درختان virtual DOM را پیمایش کرده و بر اساس آن نودهای DOM واقعی ایجاد می‌کند. این مرحله به عنوان [reactive effect](./reactivity-in-depth) انجام می‌شود، بنابراین تمام وابستگی‌های reactive که در طول mount استفاده شده‌اند، پیگیری می‌کند. -3. **Patch**: هنگامی که یک وابستگی مورد استفاده در طول mount تغییر کند، effect مجددا اجرا می‌شود. این بار، یک درخت virtual DOM جدید و به‌روزرسانی شده ایجاد می‌شود. رندرر رانتایم درخت جدید را پیمایش می‌کند، آن را با درخت قدیمی مقایسه می‌کند و به‌روزرسانی‌های لازم را بر روی DOM واقعی اعمال می‌کند. +3. **Patch**: هنگامی که یک وابستگی مورد استفاده در طول mount تغییر کند، effect مجددا اجرا می‌شود. این بار، یک درخت virtual DOM جدید و به‌روزرسانی شده ایجاد می‌شود. رندرر رانتایم درخت جدید را پیمایش کرده، آن را با درخت قدیمی مقایسه می‌کند و به‌روزرسانی‌های لازم را بر روی DOM واقعی اعمال می‌کند. ![render pipeline](./images/render-pipeline.png) @@ -50,23 +51,24 @@ const vnode = { ## Templates در مقابل Render Functions {#templates-vs-render-functions} -تمپلیت‌های Vue به render function های درخت virtual DOM کامپایل می‌شوند. Vue همچنین APIهایی را فراهم می‌کند که به ما اجازه می‌دهد مرحله کامپایل تمپلیت را رد کنیم و مستقیماً render functionها را بنویسیم. render function ها نسبت به تمپلیت‌ها در مواجهه با منطق بسیار پویا و انعطاف‌پذیرتر هستند، زیرا می‌توانید با استفاده از کامل قدرت جاوااسکریپت با vnodeها کار کنید. +تمپلیت‌های Vue به render function های درخت virtual DOM کامپایل می‌شوند. Vue همچنین API هایی را فراهم می‌کند که به ما اجازه می‌دهد مرحله کامپایل تمپلیت را رد کنیم و مستقیماً render function ها را بنویسیم. render function ها نسبت به تمپلیت‌ها در نوشتن منطق، بسیار پویا و انعطاف‌پذیرتر هستند، چراکه می‌توانید به کمک تمام قابلیت های زبان جاوااسکریپت با vnode ها کار کنید. پس چرا Vue به طور پیش‌فرض تمپلیت‌ها را توصیه می‌کند؟ چند دلیل وجود دارد: -1. تمپلیت‌ها نزدیک‌تر به HTML واقعی هستند. این باعث می‌شود استفاده مجدد از اسنیپت‌های موجود HTML یا اعمال روش‌های خوب دسترسی‌پذیری یا استایل دادن با CSS و درک و اصلاح توسط طراحان قالب سایت بسیار آسان‌تر شود. - -2. تمپلیت‌ها به دلیل سینتکس خاص‌شان، تحلیل آسان‌تری دارند. این مورد اجازه می‌دهد کامپایلر تمپلیت‌های Vue بسیاری از بهینه‌سازی‌های زمان کامپایل را برای بهبود عملکرد virtual DOM (که در ادامه بحث خواهیم کرد) اعمال کند. +1. تمپلیت‌ها نزدیک‌تر به HTML واقعی هستند. این موضوع باعث می‌شود استفاده مجدد از اسنیپت‌های HTML، اعمال روش‌های خوب دسترسی‌پذیری، استایل دادن با CSS و همچنین درک کد و یا اصلاح آن توسط طراحانی که الزاما دانش برنامه نویسی ندارند، بسیار آسان‌تر شود. +2. تحلیل کد تمپلیت، به دلیل سینتکس خاص‌شان، برای کامپایلر ساده تر است. این موضوع به کامپایلر اجازه می دهد که بسیاری از بهینه‌سازی‌های زمان کامپایل را برای بهبود عملکرد virtual DOM (که در ادامه بحث خواهیم کرد) اعمال کند. -در عمل، تمپلیت‌ها برای اکثر موارد استفاده در برنامه‌ها کافی هستند. render functionها معمولاً فقط در کامپوننت‌های قابل استفاده مجدد که نیاز به مدیریت منطق رندرینگ بسیار پویا دارند، استفاده می‌شوند. استفاده از render functionها در [Render Functions & JSX](./render-function) با جزئیات مورد بحث قرار گرفته است. +در عمل و در بیشتر موارد، استفاده از تمپلیت کافی خواهد بود. render function معمولاً فقط در کامپوننت‌ های با قابل استفاده مجدد که نیاز به مدیریت منطق رندرینگ بسیار پویا دارند، استفاده می‌شوند. استفاده از render function ها در [Render Functions & JSX](./render-function) با جزئیات بیشتر مورد بحث قرار گرفته است. ## Virtual DOM آگاه از کامپایلر | Compiler-Informed Virtual DOM {#compiler-informed-virtual-dom} -پیاده‌سازی virtual DOM در React و اکثر سایر پیاده‌سازی‌ دیگر virtual DOM صرفاً در رانتایم هستند: الگوریتم reconciliation (تطابق) نمی‌تواند هیچ فرضی در مورد درخت virtual DOM ورودی داشته باشد، بنابراین برای تضمین صحت باید به طور کامل درخت را پیمایش کند و props هر vnode را مقایسه کند. علاوه بر این، حتی اگر قسمتی از درخت هرگز تغییر نکند، مجدداً vnodeهای جدیدی برای آن‌ها در هر بازرندر ایجاد می‌شود که منجر به فشار غیرضروری به حافظه می‌شود. این موضوع یکی از مواردی است که بیشترین انتقاد به virtual DOM وارد کرده است: فرایند reconciliation به نوعی "نیرومند" یا "خشن" است، چرا که بدون در نظر گرفتن بهینه‌سازی‌ها، کل درخت virtual DOM را بررسی و مقایسه می‌کند.این کار باعث افت کارایی می‌شود، اما در عوض این اطمینان را می‌دهد که رندرینگ به درستی انجام می‌شود. بنابراین می‌توان گفت این روش، کارایی را برای declarativeness (تعریفی‌بودن) و صحت قربانی می‌کند. +پیاده سازی virtual DOM در React و بیشتر فریم‌ورک های دیگر، صرفا محدود به رانتایم است: الگوریتم reconciliation (تطابق) نمی‌تواند هیچ فرضی در مورد درخت virtual DOM ورودی داشته باشد، بنابراین برای تضمین صحت، باید به طور کامل درخت را پیمایش کند و diffing را برای props هر vnode انجام دهد. علاوه بر این، حتی اگر قسمتی از درخت هرگز تغییر نکند، مجدداً vnode های جدیدی برای آن‌ها در هر بازرندر ایجاد می‌شود که منجر به فشار غیرضروری به حافظه می گردد. این موضوع یکی جدی ترین انتقاد های وارد شده به virtual DOM است: فرایند reconciliation به نوعی "نا به خردانه" است، چرا که بدون در نظر گرفتن بهینه‌سازی‌ها، کل درخت virtual DOM را بررسی و مقایسه می‌کند. این کار باعث افت کارایی می‌شود، اما در عوض این اطمینان را می‌دهد که رندرینگ به درستی انجام شود. بنابراین می‌توان گفت این روش، کارایی را برای declarative (تعریفی‌) بودن و صحت قربانی می‌کند. + +اما لزومی برای وجود تقابل بین declrative بودن و کارایی نیست. در Vue، فریم‌ورک هم کامپایلر و هم رانتایم را کنترل می‌کند. این به ما اجازه می‌دهد تا بسیاری از بهینه‌سازی‌ها را در زمان کامپایل پیاده‌سازی کنیم که فقط یک رندرر مجهز و ادغام شده می‌تواند از آن‌ها بهره ببرد. کامپایلر می‌تواند تمپلیت را به صورت استاتیک تجزیه و تحلیل کرده و راهنمایی‌هایی در کد تولید شده قرار دهد تا رانتایم بتواند هر جا که ممکن است از این راهنمایی ها به عنوان میان‌بر استفاده کند. در عین حال، همچنان قابلیت رفتن به لایه render function با هدف کنترل مستقیم‌تر در موارد خاص، برای کاربر حفظ می‌شود. -اما لزومی ندارد این‌گونه باشد. در Vue، فریم‌ورک هم کامپایلر و هم رانتایم را کنترل می‌کند. این به ما اجازه می‌دهد تا بسیاری از بهینه‌سازی‌ها را در زمان کامپایل پیاده‌سازی کنیم که فقط یک رندرر متصل شده به هم می‌تواند از آن‌ها بهره ببرد. کامپایلر می‌تواند تمپلیت را به صورت استاتیک تجزیه و تحلیل کرده و راهنمایی‌هایی در کد تولید شده بگذارد تا رانتایم بتواند هر جا که ممکن است از میان‌بر برود. در عین حال، همچنان قابلیت کاربر برای رفتن به لایه render function برای کنترل مستقیم‌تر در موارد لبه‌ای را حفظ می‌کنیم. به این رویکرد ترکیبی **Compiler-Informed Virtual DOM (Virtual DOM آگاه از کامپایلر)** می‌گوییم. +به این رویکرد ترکیبی **Compiler-Informed Virtual DOM (Virtual DOM آگاه از کامپایلر)** می‌گوییم. -در ادامه، چندین بهینه‌سازی عمده‌ای را که توسط کامپایلر تمپلیت Vue برای بهبود عملکرد رانتایم virtual DOM انجام می‌شود را بررسی خواهیم کرد. +در ادامه، چندین نمونه از بهینه‌سازی‌های کامپایلر تمپلیت Vue را (که با هدف بهبود عملکرد رانتایم virtual DOM انجام می‌دهد) بررسی خواهیم کرد. ### Static Hoisting {#static-hoisting} @@ -82,13 +84,13 @@ const vnode = { [در Template Explorer بررسی کنید](https://template-explorer.vuejs.org/#eyJzcmMiOiI8ZGl2PlxuICA8ZGl2PmZvbzwvZGl2PiA8IS0tIGhvaXN0ZWQgLS0+XG4gIDxkaXY+YmFyPC9kaXY+IDwhLS0gaG9pc3RlZCAtLT5cbiAgPGRpdj57eyBkeW5hbWljIH19PC9kaXY+XG48L2Rpdj5cbiIsIm9wdGlvbnMiOnsiaG9pc3RTdGF0aWMiOnRydWV9fQ==) -دو تگ div با متن `foo` و `bar` استاتیک هستند - مجدداً ایجاد کردن vnodeها و مقایسه آن‌ها در هر بازرندر غیرضروری است. کامپایلر Vue به صورت خودکار توابع ایجاد vnode آن‌ها را از render function خارج می‌کند و همان vnodeها را در هر رندر مجددا استفاده می‌کند. رندرر همچنین قادر است کاملاً از انجام مقایسه (diffing) خودداری کند زمانی که متوجه می‌شود vnode قدیمی و vnode جدید یکسان هستند. +دو تگ div با متن `foo` و `bar` استاتیک هستند - بنابراین ایحاد vnodeها و مقایسه آن‌ها در هر بازرندر غیرضروری است. کامپایلر Vue به صورت خودکار فراخوانی ایجاد این دسته از vnode ها را از render function خارج می‌کند و همان vnodeها را در هر رندر، مجددا استفاده می‌کند. رندرر زمانی که متوجه شود vnode قدیمی و vnode جدید یکسان هستند، از انجام مقایسه (diffing) خودداری می‌کند. -علاوه بر این، هنگامی که تعداد کافی از عناصر استاتیک پشت سر هم وجود دارد، آن‌ها در یک "static vnode" خلاصه می‌شوند که حاوی رشته HTML ساده برای تمام این نودها است ([مثال](https://template-explorer.vuejs.org/#eyJzcmMiOiI8ZGl2PlxuICA8ZGl2IGNsYXNzPVwiZm9vXCI+Zm9vPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJmb29cIj5mb288L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImZvb1wiPmZvbzwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZm9vXCI+Zm9vPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJmb29cIj5mb288L2Rpdj5cbiAgPGRpdj57eyBkeW5hbWljIH19PC9kaXY+XG48L2Rpdj4iLCJzc3IiOmZhbHNlLCJvcHRpb25zIjp7ImhvaXN0U3RhdGljIjp0cnVlfX0=)). این vnodeهای استاتیک با مستقیماً تنظیم کردن `innerHTML` در برنامه mount می‌شوند. همچنین نودهای DOM متناظر خود را در mount اولیه ذخیره می‌کنند - اگر همان قطعه محتوا در جای دیگر برنامه استفاده شود، نودهای DOM جدید با استفاده از `cloneNode()‎` بومی که بسیار کارآمد است، ایجاد می‌شوند. +علاوه بر این، هنگامی که تعداد کافی از عناصر استاتیک پشت سر هم قرار بگیرند، به عنوان یک "static vnode" در نظر گرفته می‌شوند و این vnode استاتیک حاوی رشته HTML ساده برای تمام این نودها خواهد بود ([مثال](https://template-explorer.vuejs.org/#eyJzcmMiOiI8ZGl2PlxuICA8ZGl2IGNsYXNzPVwiZm9vXCI+Zm9vPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJmb29cIj5mb288L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImZvb1wiPmZvbzwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZm9vXCI+Zm9vPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJmb29cIj5mb288L2Rpdj5cbiAgPGRpdj57eyBkeW5hbWljIH19PC9kaXY+XG48L2Rpdj4iLCJzc3IiOmZhbHNlLCJvcHRpb25zIjp7ImhvaXN0U3RhdGljIjp0cnVlfX0=)). این vnode های استاتیک با تنظیم مستقیم `innerHTML` در برنامه mount می‌شوند. همچنین نودهای DOM متناظر خود را در mount اولیه Cache می‌کنند - اگر همان قطعه محتوا در جای دیگر برنامه استفاده شود، نودهای DOM جدید با استفاده از `cloneNode()‎` که یکی از API های DOM و بسیار کارآمد است، ایجاد می‌شوند. ### Patch Flags {#patch-flags} - می‌توانیم در زمان کامپایل اطلاعات زیادی از یک element با bindingهای پویا استنباط کنیم: + می‌توانیم در زمان کامپایل، برای یک المان با Binding های پویا، اطلاعات زیادی استنباط کنیم: ```vue-html @@ -111,7 +113,7 @@ createElementVNode("div", { }, null, 2 /* CLASS */) ``` -آخرین آرگومان، `2`، یک [patch flag](https://github.com/vuejs/core/blob/main/packages/shared/src/patchFlags.ts) است. یک عنصر می‌تواند چندین patch flag داشته باشد که در یک عدد مجزا ترکیب می‌شوند. سپس رندرر رانتایم می‌تواند با استفاده از [عملیات bitwise](https://en.wikipedia.org/wiki/Bitwise_operation) بر روی این flagها بررسی کند که آیا نیاز به انجام کار خاصی دارد یا خیر: +آخرین آرگومان، `2`، یک [patch flag](https://github.com/vuejs/core/blob/main/packages/shared/src/patchFlags.ts) است. یک عنصر می‌تواند چندین patch flag داشته باشد که در قالب یک عدد ترکیب می‌شوند. سپس رندرر رانتایم می‌تواند با استفاده از [عملیات bitwise](https://en.wikipedia.org/wiki/Bitwise_operation) بر روی این flagها بررسی کند که آیا نیاز به انجام کار خاصی دارد یا خیر: ```js if (vnode.patchFlag & PatchFlags.CLASS /* 2 */) { @@ -119,9 +121,9 @@ if (vnode.patchFlag & PatchFlags.CLASS /* 2 */) { } ``` -بررسی‌های bitwise بسیار سریع هستند. با patch flagها، Vue قادر است کمترین مقدار کار لازم را هنگام به‌روزرسانی عناصر با dynamic binding ها انجام دهد. +بررسی‌های bitwise بسیار سریع هستند. با patch flagها، Vue قادر است کمینه کار لازم را هنگام به‌روزرسانی عناصر با dynamic binding ها انجام دهد. -Vue همچنین نوع children یک vnode را کدگذاری می‌کند. به عنوان مثال، تمپلیتی که چندین نود ریشه دارد به عنوان یک فرگمنت نمایش داده می‌شود. در اکثر موارد، مطمئن هستیم که ترتیب این نودهای ریشه هرگز تغییر نمی‌کند، بنابراین این اطلاعات نیز می‌تواند به عنوان یک patch flag به رانتایم ارائه شود: +Vue همچنین نوع children یک vnode را کدگذاری می‌کند. به عنوان مثال، تمپلیتی که چندین نود ریشه دارد به عنوان یک فرگمنت (Fragment) در نظر گرفته می‌شود. در اکثر موارد، مطمئن هستیم که ترتیب این نودهای ریشه هرگز تغییر نمی‌کند، بنابراین این اطلاعات نیز می‌تواند به عنوان یک patch flag به رانتایم ارائه شود: ```js{4} export function render() { @@ -131,7 +133,7 @@ export function render() { } ``` -بنابراین رانتایم می‌تواند کاملاً از تطابق ترتیب فرزندان برای فرگمنت ریشه صرف‌نظر کند. +بنابراین رانتایم می‌تواند کاملاً از تطابق ترتیب فرزندان برای فرگمنت ریشه، صرف‌نظر کند. ### Tree Flattening {#tree-flattening} @@ -145,9 +147,9 @@ export function render() { } ``` -مفهوماً، یک "block" قسمتی از تمپلیت است که ساختار داخلی ثابتی دارد. در این مورد، کل تمپلیت یک block دارد زیرا حاوی هیچ دستورالعمل ساختاری مانند `v-if` و `v-for` نیست. +مفهوماً، یک "block" قسمتی از تمپلیت است که ساختار داخلی پایداری دارد. در این مورد، کل تمپلیت یک block دارد چراکه حاوی هیچ دستورالعمل ساختاری، مانند `v-if` و `v-for` نیست. -هر بلوکی هرگونه نودهای فرزند (نه فقط فرزندان مستقیم) که patch flags دارند را رهگیری می‌کند. به عنوان مثال: +هر بلوک، تمامی نودهای فرزند خود (و نه فقط فرزندان لایه اول) را که patch flags دارند، رهگیری می‌کند. به عنوان مثال: ```vue-html{3,5}
@@ -159,7 +161,7 @@ export function render() {
``` -نتیجه یک آرایه تخت‌شده‌است (flattened array) که فقط حاوی نودهای فرزند پویا است: +نتیجه یک آرایه تخت‌شده‌ (flattened array) است که فقط حاوی نودهای فرزند پویا است: ``` div (block root) @@ -167,7 +169,7 @@ div (block root) - div with {{ bar }} binding ``` -هنگامی که این کامپوننت نیاز به بازرندر دارد، فقط نیاز به پیمایش درخت جدید به جای درخت کامل دارد. این را **Tree Flattening** می‌نامند و تعداد نودهایی که نیاز به پیمایش در طول تطابق virtual DOM دارند را به طور قابل توجهی کاهش می‌دهد. قسمت‌های استاتیک تمپلیت به طور مؤثری رد می‌شود. +هنگامی که این کامپوننت نیاز به بازرندر دارد، فقط نیاز به پیمایش درخت تخت شده به جای درخت کامل است. این مفهوم را **Tree Flattening** می‌نامند، این فرآیند تعداد نودهایی که نیاز به پیمایش در طول تطابق virtual DOM دارند، به طور قابل توجهی کاهش می‌دهد. در نتیجه این فرآنید، قسمت‌های استاتیک تمپلیت به طور مؤثری رد می‌شود. دستورالعمل‌های `v-if` و `v-for` نودهای block جدید ایجاد خواهند کرد: @@ -181,12 +183,12 @@ div (block root)
``` -هر block والد یک آرایه‌ای از فرزندان پویایش را نگه می‌دارد. بنابراین وقتی block والد نیاز به بازرندر دارد، فقط نیاز به بررسی آرایه فرزندان پویای خودش دارد تا بفهمد چه چیزی نیاز به به‌روزرسانی دارد. +هر block والد آرایه‌ای از فرزندان پویا خود را نگه می‌دارد. بنابراین وقتی block والد نیاز به بازرندر دارد، فقط نیاز به بررسی آرایه فرزندان پویای خودش را داشته تا بفهمد چه چیزی نیاز به به‌روزرسانی دارد. ### تأثیر بر SSR Hydration {#impact-on-ssr-hydration} هم patch flag ها و هم tree flattening، عملکرد [SSR Hydration](/guide/scaling-up/ssr#client-hydration) Vue را نیز به طور قابل توجهی بهبود می‌بخشند: -- hydration تک عنصر می‌تواند مسیرهای سریعی بر اساس patch flag برای vnode متناظر انتخاب کند. +- در فرآیند hydration یک عنصر، می‌توان مسیرهای سریعی بر اساس patch flag های vnode متناظر آن عنصر، انتخاب کرد. -- فقط نودهای block و فرزندان پویای آن‌ها نیاز به پیمایش در طول hydration دارند، به طور مؤثر hydration جزئی در سطح تمپلیت را محقق می‌کند. +- در طول hydration، تنها نیار به پیمایش نودهای block و فرزندان پویای آن‌ها است، که این موضوع به طور مؤثر hydration جزئی (Partial Hydration) را در سطح تمپلیت، محقق می‌کند.