TBT (Total Blocking Time) یا «کل زمان مسدودسازی» یکی از معیارهای کلیدی عملکرد وب در گزارش Lighthouse است که مستقیماً بر تجربه کاربری اثر می‌گذارد و در سنجش کیفیت پاسخ‌گویی سایت، نقش مکمل INP (Interaction to Next Paint) را ایفا می‌کند. این معیار، مجموع زمان مسدودسازی Main Thread توسط Long Tasks را در بازه بین FCP (First Contentful Paint) و TTI (Time to Interactive) اندازه‌می‌گیرد و به‌عنوان یک شاخص آزمایشگاهی، تصویر دقیقی از توان پاسخ‌گویی سایت ارائه می‌دهد. برخلاف INP که در داده واقعی کاربران سنجیده می‌شود، TBT به‌عنوان معیار آزمایشگاهی در Lighthouse و ابزارهای مشابه، امکان تحلیل دقیق‌تر گلوگاه‌های پردازش را فراهم می‌کند. آستانه TBT خوب زیر ۲۰۰ میلی‌ثانیه، نیازمند بهبود بین ۲۰۰ تا ۶۰۰ میلی‌ثانیه و ضعیف بالای ۶۰۰ میلی‌ثانیه است. کاهش TBT نیازمند یک استراتژی چندلایه است: تقسیم Long Tasks به قطعات کوچک‌تر، Yield کردن هدفمند Main Thread، انتقال محاسبات سنگین به Web Worker، بهینه‌سازی Event Handlerها و کاهش کار DOM. در پروژه‌های واقعی، دیده‌ام که سایت‌هایی که TBT را جدی می‌گیرند، در بلندمدت تجربه پاسخ‌گویی سریع‌تر و نرخ تبدیل بالاتری تجربه می‌کنند. این معیار، پل میان تحلیل آزمایشگاهی و تجربه واقعی کاربر است و درک درست آن، پیش‌نیاز هر استراتژی بهینه‌سازی مدرن محسوب می‌شود.

در پروژه‌های متعدد بهینه‌سازی، به‌روشنی دیده‌ام که TBT، برخلاف INP که در داده واقعی سنجیده می‌شود، ابزار دقیقی برای تحلیل گلوگاه‌های Main Thread فراهم می‌کند. تیم‌هایی که TBT را جدی می‌گیرند، در تشخیص دقیق منبع مسدودسازی و اولویت‌بندی بهینه‌سازی موفق‌ترند.

TBT چیست و چه چیزی را می‌سنجد؟

TBT (Total Blocking Time) یا کل زمان مسدودسازی، معیاری است که مجموع زمان مسدودسازی Main Thread توسط Long Tasks را در بازه بین FCP (First Contentful Paint) و TTI (Time to Interactive) اندازه‌می‌گیرد. این معیار، به‌عنوان یک شاخص آزمایشگاهی در Lighthouse و ابزارهای مشابه سنجیده می‌شود و مکمل INP در تحلیل تجربه پاسخ‌گویی است.

نکته کلیدی در تعریف TBT، قید «بازداری بین FCP و TTI» است. Long Tasks پیش از FCP یا پس از TTI در محاسبه TBT لحاظ نمی‌شوند. این بازه، دقیقاً همان دوره‌ای است که کاربر برای اولین بار محتوا را می‌بیند اما هنوز نمی‌تواند با آن تعامل داشته باشد. مسدودسازی Main Thread در این بازه، مستقیماً به تأخیر در پاسخ به تعامل کاربر منجر می‌شود.

Long Task چیست؟

Long Task به وظیفه‌ای گفته می‌شود که بیش از ۵۰ میلی‌ثانیه Main Thread را اشغال می‌کند. هر Long Task، بخشی از زمان خود را به‌عنوان Blocking Time ثبت می‌کند که در محاسبه TBT لحاظ می‌شود.

محاسبه Blocking Time برای هر Long Task بر پایه فرمول زیر است:

Blocking Time = Task Duration - 50ms

برای مثال، اگر یک Long Task ۲۰۰ میلی‌ثانیه طول بکشد، Blocking Time آن ۱۵۰ میلی‌ثانیه است. مجموع این Blocking Timeها در بازه FCP تا TTI، به‌عنوان TBT گزارش می‌شود.

چه چیزی در TBT لحاظ می‌شود؟

  • Long Tasks در بازه FCP تا TTI: وظایفی که بیش از ۵۰ میلی‌ثانیه Main Thread را مسدود می‌کنند.
  • Blocking Time تجمعی: مجموع زمان مسدودسازی تمام Long Tasks.
  • وظایف JavaScript: اجرای اسکریپت‌ها، Event Handlerها و کارهای پردازشی.

چه چیزی در TBT لحاظ نمی‌شود؟

  • Long Tasks پیش از FCP (چون هنوز محتوایی نمایش داده نشده).
  • Long Tasks پس از TTI (چون صفحه قابل تعامل شده).
  • وظایف غیرمسدودکننده که در Thread جداگانه اجرا می‌شوند.
«TBT، معیار سکوت Main Thread است؛ هر ثانیه‌ای که Main Thread درگیر کار سنگین باشد، کاربر در انتظار می‌ماند.»

برای درک جایگاه TBT در چارچوب کلی Core Web Vitals، مقاله Core Web Vitals چیست و چرا گوگل بر آن تاکید دارد؟ نقطه شروع خوبی است. همچنین اگر می‌خواهید مبانی INP و تفاوت آن با TBT را مرور کنید، مقاله INP معیار جدید تعامل کاربر را مطالعه کنید.

چرا TBT بر تجربه کاربری اثر می‌گذارد؟

TBT بر تجربه کاربری اثر می‌گذارد چون معیار مستقیم توان پاسخ‌گویی سایت در بازه حساس میان FCP و TTI است. این بازه، دورانی است که کاربر نخستین محتوا را می‌بیند اما هنوز نمی‌تواند با آن تعامل مؤثر داشته باشد. مسدودسازی Main Thread در این بازه، تجربه کاربر را در چند لایه تحت تأثیر قرار می‌دهد.

لایه اول: تأخیر در پاسخ به تعامل

وقتی Main Thread مشغول اجرای Long Task است، نمی‌تواند به تعامل کاربر پاسخ دهد. کلیک، ضربه یا تایپ کاربر در این بازه، در صف انتظار می‌ماند و همین تأخیر، تجربه‌ای کند و ناخوشایند ایجاد می‌کند.

لایه دوم: شکاف بین دید و تعامل

کاربر در بازه FCP تا TTI، محتوا را می‌بیند اما نمی‌تواند با آن تعامل کند. این شکاف ادراکی، به احساس ناتوانی و سرخوردگی منجر می‌شود. TBT پایین، این شکاف را کاهش می‌دهد و تجربه‌ای روان‌تر ایجاد می‌کند.

لایه سوم: افزایش ادراک کندی

حتی اگر FCP سریع باشد، TBT بالا کاربر را در حالت انتظار نگه می‌دارد. این انتظار، ادراک کندی کلی سایت را افزایش می‌دهد و بر اعتبار برند اثر می‌گذارد.

لایه چهارم: کاهش تعامل اولیه

کاربری که در بازه اولیه با کندی روبرو می‌شود، تمایل کمتری به تعامل با سایت دارد. این کاهش تعامل اولیه، بر نرخ پرش و نرخ تبدیل اثر می‌گذارد.

برای درک عمیق‌تر اثر پاسخ‌گویی بر تجربه کاربر، مقاله چگونه سرعت سایت بر سئو تاثیر می‌گذارد؟ را مطالعه کنید.

TBT چگونه محاسبه می‌شود؟

محاسبه TBT، بر پایه سه گام اصلی انجام می‌شود که هر یک، بخشی از تصویر نهایی را می‌سازد.

گام اول: شناسایی Long Tasks

مرورگر، تمام وظایفی که بیش از ۵۰ میلی‌ثانیه Main Thread را اشغال می‌کنند، به‌عنوان Long Task شناسایی می‌کند. این وظایف، از طریق PerformanceObserver API با نوع longtask قابل ردیابی هستند.

گام دوم: محاسبه Blocking Time هر Long Task

برای هر Long Task، Blocking Time برابر است با مدت زمان اجرای وظیفه منهای ۵۰ میلی‌ثانیه. این ۵۰ میلی‌ثانیه، به‌عنوان آستانه ادراک انسانی در نظر گرفته می‌شود.

گام سوم: جمع‌بندی در بازه FCP تا TTI

مجموع Blocking Time تمام Long Tasks در بازه FCP تا TTI، به‌عنوان TBT نهایی گزارش می‌شود. این مجموع، به‌عنوان یک عدد بر حسب میلی‌ثانیه ارائه می‌گردد.

Long Taskمدت زمانBlocking Time
اجرای اسکریپت تحلیلی۸۰ms۳۰ms
Hydration کامپوننت اصلی۱۵۰ms۱۰۰ms
پردازش داده فیلتر۲۰۰ms۱۵۰ms
مجموع TBT—۲۸۰ms

در این مثال، سه Long Task در بازه FCP تا TTI اجرا شده‌اند و مجموع Blocking Time آنها ۲۸۰ میلی‌ثانیه است. این عدد، TBT نهایی است که در گزارش Lighthouse نمایش داده می‌شود.

برای درک ابزارهای سنجش این معیار، مقاله ابزارهای سنجش Core Web Vitals کدامند؟ را مطالعه کنید.

آستانه‌های TBT و طبقه‌بندی عملکرد

گوگل در Lighthouse، سه آستانه عملکردی برای TBT تعریف کرده که مبنای طبقه‌بندی سایت‌ها است:

  • خوب (Good): TBT زیر ۲۰۰ میلی‌ثانیه.
  • نیازمند بهبود (Needs Improvement): TBT بین ۲۰۰ تا ۶۰۰ میلی‌ثانیه.
  • ضعیف (Poor): TBT بالای ۶۰۰ میلی‌ثانیه.

آستانه ۲۰۰ میلی‌ثانیه، بازتابی از آستانه ادراک انسانی از تأخیر است. فراتر از این عدد، کاربر به‌طور محسوس کندی در پاسخ‌گویی را احساس می‌کند.

«آستانه TBT، نه یک عدد دلبخواهی، بلکه بازتابی از ظرفیت تحمل ادراک انسانی در برابر تأخیر است.»

نکته مهم این است که TBT، برخلاف INP، در داده واقعی کاربران سنجیده نمی‌شود؛ بلکه به‌عنوان یک معیار آزمایشگاهی در Lighthouse و ابزارهای مشابه گزارش می‌شود. این تفاوت، به معنای عدم اهمیت TBT نیست؛ بلکه به این معناست که TBT برای تحلیل دقیق و INP برای سنجش تجربه واقعی به کار می‌رود.

برای درک عمیق‌تر تفاوت TBT با INP و FID، مقاله چرا FID جای خود را به INP داد؟ را مطالعه کنید.

تفاوت TBT با INP و FID

TBT، INP و FID هر سه به پاسخ‌گویی سایت مربوط می‌شوند اما هر یک، بُعد متفاوتی را می‌سنجند. درک این تفاوت، برای تفسیر دقیق گزارش‌ها ضروری است.

TBT در برابر INP

TBT یک معیار آزمایشگاهی است که مجموع زمان مسدودسازی Main Thread را در بازه FCP تا TTI می‌سنجد، در حالی که INP یک معیار داده واقعی است که تأخیر تمام تعامل‌های کاربر را در طول عمر صفحه اندازه‌می‌گیرد. TBT برای تحلیل دقیق گلوگاه‌های پردازش مناسب است و INP برای سنجش تجربه واقعی کاربر.

TBT در برابر FID

FID (First Input Delay) یک معیار داده واقعی بود که تنها تأخیر اولین تعامل کاربر را می‌سنجید. TBT یک معیار آزمایشگاهی است که مجموع زمان مسدودسازی Main Thread را در بازه مشخصی می‌سنجد. این دو، ابعاد متفاوتی از پاسخ‌گویی را اندازه‌می‌گیرند. FID در مارس ۲۰۲۴ بازنشسته شد و جای خود را به INP داد.

ویژگیTBTINPFID
نوع سنجشآزمایشگاهیداده واقعیداده واقعی (بازنشسته)
دامنه سنجشFCP تا TTIتمام عمر صفحهاولین تعامل
آستانه خوبزیر ۲۰۰msزیر ۲۰۰msزیر ۱۰۰ms
وضعیت فعلیفعال در Lighthouseفعال در Core Web Vitalsبازنشسته

نکته کلیدی این است که TBT و INP مکمل یکدیگرند: TBT امکان تحلیل دقیق گلوگاه‌های پردازش در محیط آزمایشگاهی را فراهم می‌کند، در حالی که INP تجربه واقعی کاربر را در شرایط متنوع سنجیده می‌شود. تیم‌هایی که هر دو معیار را جدی می‌گیرند، تصویر کاملی از عملکرد سایت خود دارند.

برای درک تاریخچه FID و دلایل بازنشستگی آن، مقاله FID و تاریخچه آن در Core Web Vitals را مطالعه کنید. همچنین اگر می‌خواهید تفاوت این معیارها در موبایل را ببینید، مقاله بهینه‌سازی INP برای موبایل نکات عملی مهمی ارائه می‌دهد.

Long Tasks و نقش آن در TBT

Long Task به وظیفه‌ای گفته می‌شود که بیش از ۵۰ میلی‌ثانیه Main Thread را اشغال می‌کند. این وظایف، منبع اصلی TBT در سایت‌های مدرن هستند.

منابع رایج Long Tasks

  • Hydration سنگین: در اپلیکیشن‌های فریم‌ورک‌محور مانند React، Vue و Angular.
  • اجرای اسکریپت‌های تحلیلی و تبلیغاتی: اسکریپت‌های شخص ثالث که در لحظه بارگذاری اجرا می‌شوند.
  • پردازش داده‌های بزرگ: مرتب‌سازی، فیلتر یا محاسبات آماری در JavaScript.
  • دستکاری گسترده DOM: افزودن، حذف یا به‌روزرسانی تعداد زیادی از عناصر.
  • اجرای کدهای همگام: بارگذاری همگام منابع یا درخواست‌های شبکه‌ای مسدودکننده.

چرا ۵۰ میلی‌ثانیه؟

آستانه ۵۰ میلی‌ثانیه، بازتابی از ادراک انسانی از تأخیر است. تجربه‌های تجربی نشان داده که کاربر، تأخیر کمتر از ۵۰ میلی‌ثانیه را به‌عنوان «آنِی» درک می‌کند. فراتر از این آستانه، تأخیر به‌طور محسوس احساس می‌شود.

تقسیم Long Tasks

مؤثرترین راهکار در مواجهه با Long Tasks، تقسیم آنها به قطعات کوچک‌تر است. با Yield کردن بین قطعات، مرورگر فرصتی برای پاسخ به تعامل کاربر پیدا می‌کند. این رویکرد، به‌طور مستقیم TBT را کاهش می‌دهد.

«هر Long Task، یک دیوار در مسیر پاسخ‌گویی سایت است؛ تقسیم این دیوار، تجربه کاربر را روان‌تر می‌کند.»

در پروژه‌های واقعی، دیده‌ام که تقسیم Long Tasks به قطعات ۲۰ تا ۳۰ میلی‌ثانیه‌ای، TBT را به‌طور محسوس کاهش می‌دهد. برای درک عمیق‌تر این حوزه، مقاله بهینه سازی جاوااسکریپت را مطالعه کنید.

Main Thread و محدودیت تک‌رشته‌ای

Main Thread مرورگر، مسئول اجرای JavaScript، محاسبه استایل، چیدمان و رندر بصری است. این Thread، نقش محوری در TBT دارد چون هر Long Task روی همین Thread اجرا می‌شود.

محدودیت تک‌رشته‌ای بودن

Main Thread یک رشته واحد است و نمی‌تواند چند کار را هم‌زمان انجام دهد. اگر مشغول اجرای یک Long Task باشد، نمی‌تواند به تعامل کاربر پاسخ دهد. این محدودیت، ریشه اصلی TBT بالا در بسیاری از سایت‌ها است.

تقسیم کار بین Threadها

یکی از مؤثرترین راهکارها برای کاهش TBT، انتقال کارهای سنگین به Threadهای دیگر است. Web Workers، Service Workers و OffscreenCanvas، ابزارهای اصلی برای این انتقال هستند.

Yield کردن Main Thread

در JavaScript، تکنیک‌های Yield کردن Main Thread — مانند استفاده از scheduler.yield()، requestIdleCallback یا setTimeout — به مرورگر امکان می‌دهند که بین کارهای سنگین، فرصتی برای پاسخ به تعامل کاربر پیدا کند.

Barriers to Yield

در برخی موارد، Yield کردن ممکن است با محدودیت‌هایی روبرو شود. برای مثال، اگر Event Handler نیازمند دسترسی همگام به DOM باشد، Yield کردن می‌تواند به ناسازگاری داده منجر شود. در این شرایط، باید با دقت بیشتری برنامه‌ریزی انجام شود.

منابع رایج TBT بالا در سایت‌ها

TBT بالا در سایت‌های مدرن، از چند منبع اصلی ناشی می‌شود. شناخت این منابع، پیش‌نیاز هر استراتژی بهینه‌سازی است.

منبع اول: Hydration سنگین

در اپلیکیشن‌های فریم‌ورک‌محور، فرآیند Hydration می‌تواند Main Thread را برای مدت طولانی اشغال کند. این فرآیند، ریشه اصلی TBT بالا در سایت‌های SPA است.

منبع دوم: اسکریپت‌های شخص ثالث

اسکریپت‌های تحلیلی، تبلیغاتی و چت آنلاین، به‌طور معمول بار پردازشی زیادی بر Main Thread تحمیل می‌کنند. در سایت‌هایی که از ابزارهای متعدد استفاده می‌کنند، این منبع می‌تواند به‌تنهایی TBT را از آستانه مطلوب عبور دهد.

منبع سوم: پردازش داده‌های بزرگ

پردازش داده‌های بزرگ در JavaScript — مانند مرتب‌سازی، فیلتر یا محاسبات آماری — می‌تواند به Long Taskهای طولانی منجر شود.

منبع چهارم: دستکاری گسترده DOM

افزودن، حذف یا به‌روزرسانی تعداد زیادی از عناصر DOM در یک مرحله، به محاسبه مجدد استایل و چیدمان منجر می‌شود که زمان‌بر است.

منبع پنجم: بارگذاری همگام منابع

بارگذاری همگام فایل‌های CSS و JavaScript، Main Thread را تا زمان دانلود مسدود می‌کند و به افزایش TBT منجر می‌شود.

در تجربه‌های واقعی، دیده‌ام که ترکیب این منابع، تصویر پیچیده‌ای می‌سازد که بدون تحلیل دقیق، تشخیص گلوگاه اصلی را دشوار می‌کند. برای درک اشتباهات رایج در این حوزه، مقاله چه اشتباهاتی در بهینه‌سازی Core Web Vitals رایج است؟ را مطالعه کنید.

اندازه‌گیری TBT با Lighthouse و DevTools

اندازه‌گیری TBT، برخلاف INP، به‌طور کامل در محیط آزمایشگاهی انجام می‌شود. ابزارهای اصلی اندازه‌گیری TBT عبارتند از:

Lighthouse

Lighthouse، ابزار جامع گوگل برای تحلیل عملکرد صفحه، TBT را به‌عنوان یکی از معیارهای اصلی گزارش می‌دهد. این ابزار، Long Tasks را شناسایی و مجموع Blocking Time آنها را محاسبه می‌کند.

PageSpeed Insights

PageSpeed Insights، نسخه آنلاین Lighthouse است که TBT را در بخش داده آزمایشگاهی گزارش می‌دهد. این ابزار، فرصت‌های بهینه‌سازی را نیز پیشنهاد می‌کند.

Chrome DevTools

Performance panel در Chrome DevTools، امکان تحلیل دقیق Long Tasks را فراهم می‌کند. این ابزار، هر Long Task را به‌صورت جداگانه نمایش می‌دهد و زمان شروع، مدت و علت آن را مشخص می‌کند.

WebPageTest

WebPageTest، ابزار پیشرفته‌ای برای تحلیل عمیق TBT است. این ابزار، امکان شبیه‌سازی شرایط مختلف شبکه و دستگاه را فراهم می‌کند.

PerformanceObserver API

برای سنجش برنامه‌نویسی‌شده TBT در کد، می‌توان از PerformanceObserver با نوع longtask استفاده کرد. این API، امکان ثبت دقیق Long Tasks و محاسبه TBT را در محیط آزمایشگاهی فراهم می‌کند.

در پروژه‌های واقعی، ترکیب این ابزارها رویکرد توصیه‌شده است. Lighthouse و PageSpeed Insights برای تحلیل سریع، Chrome DevTools برای تحلیل عمیق و WebPageTest برای شبیه‌سازی شرایط. برای آشنایی با ابزارهای تکمیلی، مقاله ابزارهای بهینه‌سازی عملکرد وب را مطالعه کنید.

تقسیم Long Tasks به قطعات کوچک

تقسیم Long Tasks به قطعات کوچک‌تر، مؤثرترین راهکار برای کاهش TBT است. این تکنیک، Main Thread را در فواصل منظم آزاد می‌کند و فرصت پاسخ به تعامل کاربر را فراهم می‌سازد.

الگوی تقسیم وظایف

الگوی پیشنهادی برای تقسیم Long Tasks:

  1. وظیفه بزرگ را به قطعات ۲۰ تا ۳۰ میلی‌ثانیه‌ای تقسیم کنید.
  2. بین قطعات، یک Yield اعمال کنید.
  3. در هر Yield، بررسی کنید که آیا تعاملی در انتظار است.
  4. اگر تعاملی در انتظار باشد، Yield با اولویت بالا اعمال شود.

تکنیک‌های تقسیم

  • loop splitting: حلقه‌های بزرگ را به قطعات کوچک‌تر تقسیم کنید.
  • array chunking: پردازش آرایه‌های بزرگ را به قطعات تقسیم کنید.
  • recursive scheduling: از توابع بازگشتی با Yield استفاده کنید.
  • generator functions: از Generatorها برای کنترل دقیق Yield استفاده کنید.

الگوی Generator

Generator functions امکان Yield کردن دقیق در نقاط مشخص را فراهم می‌کنند. این الگو، برای تقسیم وظایف پیچیده مناسب است.

«تقسیم وظایف، یک تسلیم نیست؛ یک تصمیم مهندسی برای توزیع عادلانه زمان پردازش بین کارهای سنگین و تعامل کاربر است.»

در پروژه‌های واقعی، دیده‌ام که تقسیم Long Tasks به قطعات کوچک، TBT را تا ۵۰ درصد کاهش می‌دهد. این تکنیک، به‌ویژه در سایت‌هایی که پردازش داده‌های بزرگ دارند، بسیار مؤثر است.

تکنیک‌های Yield کردن Main Thread

Yield کردن Main Thread، به معنای دادن فرصت به مرورگر برای پاسخ به تعامل کاربر در بین وظایف سنگین است. در ادامه، تکنیک‌های اصلی این حوزه بررسی می‌شوند.

تکنیک اول: scheduler.yield()

مدرن‌ترین تکنیک Yield کردن، استفاده از scheduler.yield() است. این API، کار را با اولویت پایین‌تر به تعویق می‌اندازد و فرصت پاسخ به تعامل را فراهم می‌کند. این تکنیک در مرورگرهای جدید پشتیبانی می‌شود.

تکنیک دوم: setTimeout با تأخیر صفر

روش سنتی‌تر، استفاده از setTimeout(callback, 0) است. این تکنیک در همه مرورگرها پشتیبانی می‌شود اما از scheduler.yield دقیق‌تر نیست.

تکنیک سوم: requestIdleCallback

برای کارهای غیرحیاتی، requestIdleCallback به مرورگر اعلام می‌کند که کار را در زمان بیکاری اجرا کند. این تکنیک، برای کارهای پس‌زمینه مناسب است.

تکنیک چهارم: isInputPending()

این API امکان تشخیص وجود تعامل در انتظار را فراهم می‌کند. اگر تعاملی در انتظار باشد، می‌توان کار سنگین را به تعویق انداخت تا به آن پاسخ داده شود.

تکنیک پنجم: MessageChannel

استفاده از MessageChannel برای Yield کردن، در برخی سناریوها سریع‌تر از setTimeout عمل می‌کند.

تکنیکسرعت Yieldپشتیبانی
scheduler.yield()بالامحدود
setTimeout(0)پایینگسترده
requestIdleCallbackمتوسطگسترده
MessageChannelبالاگسترده
isInputPending()متغیرمحدود

در پروژه‌های واقعی، دیده‌ام که ترکیب این تکنیک‌ها، TBT را به‌طور محسوس کاهش می‌دهد. برای درک عمیق‌تر مفاهیم پیشرفته JavaScript، مقاله بهینه سازی جاوااسکریپت را مطالعه کنید.

انتقال محاسبات به Web Worker

Web Worker، یکی از مؤثرترین راهکارها در کاهش TBT است. این تکنولوژی، امکان اجرای کد JavaScript در یک رشته جداگانه را فراهم می‌کند و Main Thread را برای پاسخ به تعامل آزاد نگه می‌دارد.

کارهایی که مناسب Web Worker هستند

  • پردازش داده‌های بزرگ (مرتب‌سازی، فیلتر، محاسبات آماری).
  • تجزیه و تحلیل متن یا JSON.
  • رمزنگاری و رمزگشایی.
  • پردازش تصویر و ویدئو.
  • محاسبات ریاضی سنگین.
  • پردازش داده‌های شبکه‌ای پس از دریافت.

محدودیت‌های Web Worker

  • عدم دسترسی به DOM.
  • عدم دسترسی به window.
  • ارتباط از طریق postMessage که هزینه انتقال داده دارد.
  • محدودیت در دسترسی به برخی APIهای مرورگر.

الگوی استفاده

  1. محاسبات سنگین را از Main Thread جدا کنید.
  2. داده را از طریق postMessage به Worker ارسال کنید.
  3. Worker محاسبات را انجام دهد و نتیجه را برگرداند.
  4. Main Thread نتیجه را دریافت کند و بر اساس آن، DOM را به‌روزرسانی نماید.
«Web Worker، سپر محافظ Main Thread است؛ هر محاسبه‌ای که به Worker منتقل شود، یک فرصت پاسخ سریع به کاربر بازمی‌گرداند.»

در پروژه‌های واقعی، دیده‌ام که انتقال محاسبات سنگین به Web Worker، TBT را در برخی سایت‌ها تا ۶۰ درصد کاهش داده است. این تکنیک، به‌ویژه در سایت‌هایی که پردازش داده‌های بزرگ دارند، بسیار مؤثر است.

بهینه‌سازی Event Handlerها

Event Handlerها، بخش بزرگی از زمان پردازش تعامل را اشغال می‌کنند. بهینه‌سازی آنها، یکی از مؤثرترین راهکارها در کاهش TBT است.

راهکار اول: Debounce و Throttle

برای رویدادهای پرتکرار مانند scroll، resize و input، استفاده از Debounce و Throttle از اجرای مکرر و سنگین Handler جلوگیری می‌کند.

راهکار دوم: Defer کارهای غیرحیاتی

اگر بخشی از کار Event Handler بلافاصله لازم نیست — مانند ثبت آمار یا درخواست شبکه‌ای — با استفاده از requestIdleCallback یا setTimeout به تعویق بیندازید.

راهکار سوم: Passive Event Listeners

برای رویدادهای اسکرول و تاچ، استفاده از { passive: true } در تعریف Event Listener، از مسدود شدن تعامل جلوگیری می‌کند.

راهکار چهارم: حذف Event Listenerهای اضافی

هر Event Listener اضافی، بار پردازشی بر مرورگر تحمیل می‌کند. حذف Listenerهایی که در صفحات خاص استفاده نمی‌شوند، TBT را بهبود می‌بخشد.

راهکار پنجم: Event Delegation

به‌جای تعریف Event Listener برای هر عنصر، از Event Delegation در والد مشترک استفاده کنید. این کار، تعداد Listenerها و بار پردازشی را کاهش می‌دهد.

در پروژه‌های واقعی، دیده‌ام که بهینه‌سازی Event Handlerها به‌تنهایی می‌تواند TBT را تا ۳۰ درصد کاهش دهد. این اقدام، به‌ویژه در سایت‌هایی که تعامل‌های زیادی دارند، بسیار مؤثر است.

کاهش کار DOM و رندر

دستکاری DOM، یکی از سنگین‌ترین کارها روی Main Thread است. کاهش این کار، به‌طور مستقیم TBT را بهبود می‌بخشد.

راهکار اول: DocumentFragment

برای اضافه کردن چندین عنصر به DOM، از DocumentFragment استفاده کنید. این تکنیک، تنها یک بار تغییر DOM را اعمال می‌کند.

راهکار دوم: Batch تغییرات DOM

تغییرات DOM را به‌صورت دسته‌ای اعمال کنید. تغییرات پراکنده، منجر به محاسبه مجدد استایل و چیدمان در هر مرحله می‌شود.

راهکار سوم: تعویق تغییرات غیرضروری

تغییرات DOM که بلافاصله لازم نیستند، با requestIdleCallback یا setTimeout به تعویق بیفتند.

راهکار چهارم: کاهش عمق DOM

DOM با عمق زیاد، محاسبه استایل و چیدمان را کندتر می‌کند. کاهش عمق DOM، این بار را کاهش می‌دهد.

راهکار پنجم: پرهیز از Forced Synchronous Layout

خواندن خصوصیات چیدمان (مانند offsetHeight) بلافاصله پس از تغییر DOM، باعث Forced Synchronous Layout می‌شود که بسیار پرهزینه است. این خواندن‌ها باید به‌صورت دسته‌ای و پیش از تغییرات DOM انجام شوند.

در تجربه‌های واقعی، دیده‌ام که کاهش کار DOM، به‌تنهایی می‌تواند TBT را تا ۲۵ درصد کاهش دهد.

مدیریت اسکریپت‌های شخص ثالث

اسکریپت‌های شخص ثالث، یکی از منابع اصلی TBT بالا در سایت‌های مدرن هستند. این اسکریپت‌ها — شامل ابزارهای تحلیلی، تبلیغاتی، چت آنلاین و A/B Testing — بار پردازشی زیادی بر Main Thread تحمیل می‌کنند.

راهکار اول: ممیزی اسکریپت‌های شخص ثالث

فهرستی از تمام اسکریپت‌های شخص ثالث سایت تهیه کنید و اثر هر یک را بر TBT بررسی نمایید. ابزارهایی مانند WebPageTest و Chrome DevTools امکان این ممیزی را فراهم می‌کنند.

راهکار دوم: Defer یا Async کردن

اسکریپت‌های شخص ثالث را با defer یا async بارگذاری کنید تا از مسدود شدن رندر اولیه جلوگیری شود.

راهکار سوم: تعویق تا تعامل کاربر

اسکریپت‌هایی که بلافاصله لازم نیستند — مانند چت آنلاین یا ویجت‌های تبلیغاتی — را تا اولین تعامل کاربر به تعویق بیندازید.

راهکار چهارم: انتخاب جایگزین‌های سبک‌تر

برخی از اسکریپت‌های سنگین، جایگزین‌های سبک‌تری دارند. مهاجرت به این جایگزین‌ها، بار پردازشی را کاهش می‌دهد.

راهکار پنجم: Self-Hosting برخی اسکریپت‌ها

در برخی موارد، Self-Hosting اسکریپت (بارگذاری از دامنه خودی) زمان بارگذاری را کاهش می‌دهد.

در پروژه‌های واقعی، دیده‌ام که ممیزی و بهینه‌سازی اسکریپت‌های شخص ثالث، می‌تواند TBT را تا ۴۰ درصد کاهش دهد. برای درک عمیق‌تر این حوزه، مقاله چگونه زمان بارگذاری سایت را کاهش دهیم؟ را مطالعه کنید.

کاهش TBT در سایت‌های وردپرسی

وردپرس، به‌عنوان یکی از رایج‌ترین پلتفرم‌های وب، چالش‌های خاص خود را در حوزه TBT دارد.

چالش اول: انباشت اسکریپت‌های افزونه‌ها

هر افزونه، مجموعه‌ای از اسکریپت‌ها را به صفحه اضافه می‌کند. در سایت‌هایی با ۳۰ تا ۵۰ افزونه فعال، مجموع این اسکریپت‌ها می‌تواند Main Thread را برای مدت طولانی مشغول کند.

چالش دوم: Hydration در Page Builderها

بسیاری از Page Builderهای وردپرس — مانند Elementor و Divi — فرآیند Hydration سنگینی دارند که TBT را افزایش می‌دهد.

چالش سوم: اسکریپت‌های تحلیلی و تبلیغاتی

افزونه‌های تحلیلی، تبلیغاتی و Tracking، به‌طور معمول Main Thread را مشغول می‌کنند.

راهکارها

  • حذف افزونه‌های غیرضروری.
  • تغییر Page Builder به گزینه‌های سبک‌تر.
  • Defer یا Async کردن اسکریپت‌های افزونه‌ها.
  • Self-Hosting اسکریپت‌های شخص ثالث.
  • استفاده از افزونه‌های بهینه‌سازی JavaScript.
  • فعال‌سازی کش صفحه و کش اشیاء.

برای راهنمای جامع بهینه‌سازی Core Web Vitals در وردپرس، مقاله Core Web Vitals در وردپرس چگونه بهبود می‌یابد؟ را مطالعه کنید. همچنین اگر روی فروشگاه ووکامرس کار می‌کنید، مقاله افزایش سرعت فروشگاه ووکامرس نکات عملی مهمی ارائه می‌دهد.

TBT در موبایل: چرا سخت‌تر است؟

TBT در موبایل، به‌طور طبیعی بالاتر از دسکتاپ است. دلایل این تفاوت در چند لایه قابل تفکیک است:

  • پردازش کندتر: CPUهای موبایل، ظرفیت پردازشی کمتری دارند و یک Long Task که در دسکتاپ ۱۰۰ میلی‌ثانیه طول می‌کشد، در موبایل ممکن است ۳۰۰ میلی‌ثانیه طول بکشد.
  • حافظه محدود: رم کمتر موبایل، اجرای اسکریپت‌های سنگین را کندتر می‌کند.
  • مدیریت انرژی: سیستم‌عامل موبایل برای صرفه‌جویی در باتری، فرکانس CPU را کاهش می‌دهد.
  • شبکه ناپایدار: اتصال موبایل، ناپایدارتر از دسکتاپ است.

در پروژه‌های واقعی، دیده‌ام که سایت‌هایی که بر پایه دسکتاپ بهینه شده‌اند، در موبایل TBT بالاتری دارند. این پدیده، ریشه در نادیده گرفتن تفاوت‌های سخت‌افزاری دارد. برای درک عمیق‌تر این حوزه، مقاله چگونه Core Web Vitals را در موبایل بهبود دهیم؟ را مطالعه کنید.

اثر TBT بر نرخ تبدیل

TBT، بر خلاف تصور رایج، یک معیار صرفاً فنی نیست؛ یک سنجه اقتصادی است که به‌طور مستقیم بر نرخ تبدیل اثر می‌گذارد.

مکانیزم‌های اثر TBT بر نرخ تبدیل

  1. کاهش پاسخ‌گویی در بازه اولیه: کاربری که در بازه FCP تا TTI با تأخیر روبرو می‌شود، تجربه اولیه ضعیفی دارد.
  2. افزایش نرخ پرش: سایت‌های با TBT بالا، نرخ پرش بیشتری دارند.
  3. کاهش تعامل اولیه: کاربری که در بازه اولیه با کندی روبرو می‌شود، تمایل کمتری به تعامل دارد.
  4. کاهش تبدیل در فرم‌ها: فرم‌هایی که با تأخیر پاسخ می‌دهند، نرخ تکمیل پایین‌تری دارند.

در پروژه‌های واقعی، دیده‌ام که بهبود TBT به‌تنهایی می‌تواند نرخ تبدیل را تا ۵ تا ۱۰ درصد افزایش دهد. این اثر، در فروشگاه‌های آنلاین و سایت‌های خدماتی محسوس‌تر است. برای درک این رابطه، مقاله رابطه Core Web Vitals و نرخ تبدیل چیست؟ را مطالعه کنید.

«TBT، هزینه پنهان مسدودسازی Main Thread است؛ هر ثانیه که این Thread درگیر باشد، یک فرصت تبدیل از دست می‌رود.»

اشتباهات رایج در کاهش TBT

اشتباهاثر عملیاتی
بهینه‌سازی بدون شناسایی منبع Long Taskاتلاف منابع در لایه اشتباه
تقسیم Long Tasks بدون Yieldعدم بهبود TBT
استفاده از setTimeout با تأخیر زیاد برای Yieldافت پاسخ‌گویی کلی
انتقال بیش از حد کار به Web Workerهزینه انتقال داده و پیچیدگی
نادیده گرفتن تفاوت موبایل و دسکتاپTBT بالا در موبایل
حذف Analytics به‌جای بهینه‌سازی آناز دست دادن داده‌های تحلیلی
نصب افزونه‌های متعدد بهینه‌سازیتداخل و افت عملکرد
عدم پایش مستمربازگشت تدریجی به وضعیت قبل
تمرکز بر TBT بدون در نظر گرفتن INPتجربه نامتوازن

در تجربه‌های واقعی، بیشترین اتلاف منابع از اشتباه اول و هشتم ناشی می‌شود. تیم‌هایی که بدون شناسایی منبع Long Task وارد بهینه‌سازی می‌شوند یا پایش مستمر را جدی نمی‌گیرند، معمولاً به نتایج پایدار نمی‌رسند.

پرسش‌های پرتکرار درباره TBT

TBT چیست و چه تفاوتی با INP دارد؟

TBT (Total Blocking Time) معیاری آزمایشگاهی است که مجموع زمان مسدودسازی Main Thread توسط Long Tasks را در بازه FCP تا TTI می‌سنجد. INP (Interaction to Next Paint) معیاری داده واقعی است که تأخیر تمام تعامل‌های کاربر را در طول عمر صفحه اندازه‌می‌گیرد. این دو، مکمل یکدیگرند: TBT برای تحلیل دقیق گلوگاه‌های پردازش و INP برای سنجش تجربه واقعی. برای درک عمیق‌تر INP، مقاله INP معیار جدید تعامل کاربر را مطالعه کنید.

آستانه TBT خوب چقدر است؟

آستانه TBT خوب، زیر ۲۰۰ میلی‌ثانیه است. بازه ۲۰۰ تا ۶۰۰ میلی‌ثانیه نیازمند بهبود و بالای ۶۰۰ میلی‌ثانیه ضعیف طبقه‌بندی می‌شود. این آستانه، بر پایه آدراک انسانی از تأخیر تعریف شده است.

چگونه TBT سایت خود را اندازه‌گیری کنم؟

با استفاده از Lighthouse، PageSpeed Insights یا Chrome DevTools Performance panel. این ابزارها، Long Tasks و TBT را به‌طور دقیق گزارش می‌دهند. برای آشنایی با ابزارهای سنجش، مقاله ابزارهای سنجش Core Web Vitals کدامند؟ را ببینید.

Long Task چیست و چه ارتباطی با TBT دارد؟

Long Task به وظیفه‌ای گفته می‌شود که بیش از ۵۰ میلی‌ثانیه Main Thread را اشغال می‌کند. هر Long Task، بخشی از زمان خود را به‌عنوان Blocking Time ثبت می‌کند که در محاسبه TBT لحاظ می‌شود. تقسیم Long Tasks به قطعات کوچک‌تر، مؤثرترین راهکار کاهش TBT است.

مؤثرترین راهکار کاهش TBT چیست؟

ترکیب سه تکنیک: تقسیم Long Tasks به قطعات کوچک، Yield کردن هدفمند Main Thread و انتقال محاسبات سنگین به Web Worker. این سه، به‌طور مستقیم زمان مسدودسازی Main Thread را کاهش می‌دهند.

آیا TBT بر رتبه گوگل اثر دارد؟

TBT به‌طور مستقیم در Core Web Vitals لحاظ نمی‌شود، اما به‌عنوان یک معیار در Lighthouse سنجیده می‌شود و از طریق هم‌بستگی با INP، به‌طور غیرمستقیم بر تجربه صفحه اثر می‌گذارد. برای درک این حوزه، مقاله چگونه سرعت سایت بر سئو تاثیر می‌گذارد؟ را مطالعه کنید.

آیا TBT در موبایل بالاتر از دسکتاپ است؟

بله، به‌طور معمول. این تفاوت ناشی از پردازش کندتر، حافظه محدودتر و مدیریت انرژی دستگاه‌های موبایل است. یک Long Task که در دسکتاپ ۱۰۰ میلی‌ثانیه طول می‌کشد، در موبایل ممکن است چند برابر طول بکشد.

آیا بهینه‌سازی TBT یک‌باره است؟

خیر. TBT یک معیار پیوسته است که با هر تغییر در کد، افزونه یا محتوا می‌تواند تغییر کند. بهینه‌سازی TBT نیازمند پایش مستمر و اصلاح دوره‌ای است.

چگونه TBT را در وردپرس کاهش دهیم؟

با ترکیب چند اقدام: حذف افزونه‌های غیرضروری، Defer یا Async کردن اسکریپت‌ها، استفاده از Page Builderهای سبک، Self-Hosting اسکریپت‌های شخص ثالث و فعال‌سازی کش صفحه. برای راهنمای جامع، مقاله Core Web Vitals در وردپرس چگونه بهبود می‌یابد؟ را مطالعه کنید.

پایان‌بندی مهندسی

TBT، معیار کلیدی مسدودسازی Main Thread در بازه حساس میان FCP و TTI، اثری مستقیم بر تجربه کاربری، نرخ پرش و نرخ تبدیل دارد. این معیار، برخلاف تصور رایج، یک عدد صرفاً فنی نیست؛ یک سنجه اقتصادی است که در بلندمدت بر رشد کسب‌وکار اثر می‌گذارد. سایت‌هایی که TBT را جدی می‌گیرند، تجربه پاسخ‌گویی پایدارتری می‌سازند و در رقابت جستجو، جایگاه بهتری به دست می‌آورند.

از منظر مهندسی سطح ارشد، سه اصل در معماری کاهش TBT تعیین‌کننده است. نخست، طراحی یک لایه سیاست تقسیم وظایف (Task Scheduling Policy) که تعریف کند در چه نقاطی از کد، وظایف سنگین باید به قطعات کوچک‌تر تقسیم شوند و Yield کردن بین آنها اعمال گردد؛ این سیاست باید به‌عنوان یک قرارداد مهندسی در تمام تیم‌ها اجرا شود. دوم، پیاده‌سازی یک معماری توزیع کار که محاسبات سنگین را به Web Workerها و Service Workerها منتقل کند و Main Thread را برای پاسخ به تعامل کاربر آزاد نگه دارد. سوم، استقرار یک مکانیزم پایش پیوسته که TBT را به‌عنوان یک شاخص راهبردی در داشبورد سازمان رصد کند و هر تغییر در کد، افزونه یا معماری را به بازبینی عملکرد متصل نماید. رعایت این سه اصل، TBT را از یک عدد فنی به یک قابلیت راهبردی در معماری تجربه کاربری تبدیل می‌کند.

سازمانی که این قابلیت را بسازد، در بلندمدت تجربه پاسخ‌گویی سریع‌تر، نرخ پرش پایین‌تر و نرخ تبدیل بهتری خواهد داشت. TBT، به‌عنوان پل میان تحلیل آزمایشگاهی و تجربه واقعی کاربر، ابزار ارزشمندی برای درک گلوگاه‌های پردازش است و در ترکیب با INP، تصویر کامل تجربه پاسخ‌گویی را می‌سازد.

اگر در سایت خود تجربه‌ای از کاهش TBT دارید، برایم جالب است بدانید کدام اقدام بیشترین اثر را داشت: تقسیم Long Tasks، انتقال به Web Worker یا بهینه‌سازی اسکریپت‌های شخص ثالث. تجربه‌تان را در دیدگاه‌ها بنویسید؛ به‌ویژه اگر راه‌حل خلاقانه‌ای برای کاهش TBT در شرایط خاص به کار برده‌اید که می‌تواند برای پروژه‌های بعدی الهام‌بخش باشد. ⚡