بلاک کردن عمدی رندر با blocking="render"
خلاصهٔ کاملتر
مقاله از یه مشکل آشنای فرانتاند شروع میکنه: یه کامپوننت داری که برای رندر کردن چیدمان یا مارکآپ «درست»ش به JavaScript سمت کلاینت وابستهست. توی این حالت فقط سه انتخاب داری: یا یه «فلش» از کامپوننت بدون استایل رو قبول کنی، یا تا وقتی اسکریپت کامپوننت رو آماده کنه پنهانش کنی (که خودش میتونه پرش چیدمان بسازه)، یا با بلاک کردن رندر سعی کنی قبل از اینکه کاربر چیزی ببینه همهچی سر جاش باشه.
نویسنده توضیح میده که اسکریپتهای inline سنتی (و اسکریپتهای خارجی بدون async یا defer) پارسر-بلاککننده هستن؛ یعنی پارسر HTML از خوندن هر چیزی پایینتر از اسکریپت متوقف میشه. ولی همین هم تضمین نمیده که فلش رخ نده، چون مرورگر ممکنه همون تیکههایی که تا اون لحظه دریافت کرده رو رنگ کنه. اگه اسکریپت بلاککننده رو بالای کامپوننت ببری هم فرزندهاش هنوز پارس نشدن و نمیتونی بخونیشون؛ حتی توی connectedCallback هم زوده، چون عنصر قبل از اینکه فرزندهاش به DOM وصل بشن متصل میشه.
راهحل تمیز، یه اتریبیوت نسبتاً خوشپشتیبانی به اسم blocking="render" هست که روی تگهای ، و کار میکنه و دقیقاً همون کاری رو میکنه که میخوای:
<my-component>
<span class="inner">Thing</span>
</my-component>
<script blocking="render">
customElements.define("my-component", MyComponent);
</script>نکتهی جالب اینه که با این روش مطمئنی تا وقتی اسکریپت لود نشده هیچی رنگ نمیخوره، ولی پارسر همچنان آزاده ادامه بده حتی اگه رندر بلاک شده باشه. همین یه قدم بزرگ نسبت به اسکریپتهای بلاککنندهی سنتیه. این روش با type="module" و اسکریپتهای خارجی هم کار میکنه.
نویسنده تأکید میکنه که بلاک کردن رندر یا پارس کردن بهندرت انتخاب درستیه؛ تقریباً همیشه بهتره چیزی رو سریع نشون بدی و بعد بهتدریج بهترش کنی. ولی موارد معتبری هم هست، مثل تست A/B که یه اسکریپت خارجی ممکنه نسخههای خیلی متفاوتی از صفحه رو نشون بده.
یه مثال عملی خوب، الگوی ناوبری priority-plus هست؛ جایی که مهمترین آیتمهای منو دیده میمونن و بقیه به یه منوی سرریز منتقل میشن. چون تا وقتی آیتمها روی صفحه نباشن نمیدونی چندتاشون «جا میشن» و آیتمهای سرریز باید جای رندرشون توی DOM عوض شه (هم برای دسترسپذیری هم رفتار)، این رو نمیشه فقط با CSS حل کرد. اینجا یه اسکریپت inline بلاککننده فضا رو اندازه میگیره، آیتمهای اضافه رو جابهجا میکنه و بعد رندر آزاد میشه — بدون فلش و بدون پرش چیدمان مرئی. تنها شرطش اینه که اسکریپت کوچیک باشه و حتماً inline؛ چون لحظهای که یه درخواست شبکه اضافه کنی، سربار قابلتوجهی به کاربر تحمیل کردی.
نکات کلیدی:
- کامپوننتهای وابسته به JS یا فلش بدون استایل میدن یا پرش چیدمان
- اسکریپتهای بلاککنندهی سنتی پارسر رو متوقف میکنن ولی فلش رو تضمیناً حذف نمیکنن
- blocking="render" تا لود شدن اسکریپت جلوی رنگخوردن رو میگیره، ولی پارسر ادامه میده
- با type="module" و اسکریپتهای خارجی هم کار میکنه
- بلاک کردن رندر فقط برای موارد خاص (مثل ناوبری priority-plus یا A/B تست) توجیه داره و باید inline و کوچیک بمونه




