چندوظیفگی مشارکتی و استراتژی واگذاری وظیفه در زمانبند React را برای بهروزرسانیهای کارآمد UI و اپلیکیشنهای واکنشگرا کاوش کنید. نحوه استفاده از این تکنیک قدرتمند را بیاموزید.
چندوظیفگی مشارکتی در زمانبند React: تسلط بر استراتژی واگذاری وظیفه
در حوزه توسعه وب مدرن، ارائه یک تجربه کاربری یکپارچه و بسیار واکنشگرا از اهمیت بالایی برخوردار است. کاربران انتظار دارند که اپلیکیشنها حتی زمانی که عملیات پیچیدهای در پسزمینه در حال انجام است، فوراً به تعاملات آنها پاسخ دهند. این انتظار بار قابل توجهی را بر ماهیت تکرشتهای جاوا اسکریپت تحمیل میکند. رویکردهای سنتی اغلب هنگام مسدود شدن رشته اصلی توسط وظایف سنگین محاسباتی، منجر به فریز شدن UI یا کندی آن میشوند. اینجاست که مفهوم چندوظیفگی مشارکتی (cooperative multitasking) و به طور خاص، استراتژی واگذاری وظیفه (task yielding) در فریمورکهایی مانند زمانبند React (React Scheduler) ضروری میشود.
زمانبند داخلی React نقشی حیاتی در مدیریت نحوه اعمال بهروزرسانیها در UI ایفا میکند. برای مدت طولانی، رندرینگ React تا حد زیادی همزمان (synchronous) بود. این روش اگرچه برای اپلیکیشنهای کوچکتر مؤثر بود، اما با سناریوهای دشوارتر دست و پنجه نرم میکرد. معرفی React 18 و قابلیتهای رندرینگ همزمان (concurrent rendering) آن، یک تغییر پارادایم به همراه آورد. در هسته این تغییر، یک زمانبند پیچیده قرار دارد که از چندوظیفگی مشارکتی برای تقسیم کار رندرینگ به قطعات کوچکتر و قابل مدیریت استفاده میکند. این پست وبلاگ به طور عمیق به چندوظیفگی مشارکتی زمانبند React، با تمرکز ویژه بر استراتژی واگذاری وظیفه آن، میپردازد و توضیح میدهد که چگونه کار میکند و چگونه توسعهدهندگان میتوانند از آن برای ساخت اپلیکیشنهای با عملکرد بهتر و واکنشگراتر در مقیاس جهانی استفاده کنند.
درک ماهیت تکرشتهای جاوا اسکریپت و مشکل مسدودسازی (Blocking)
قبل از پرداختن به زمانبند React، درک چالش اساسی ضروری است: مدل اجرای جاوا اسکریپت. جاوا اسکریپت در اکثر محیطهای مرورگر، بر روی یک رشته واحد اجرا میشود. این بدان معناست که در هر زمان تنها یک عملیات میتواند اجرا شود. اگرچه این امر برخی از جنبههای توسعه را ساده میکند، اما برای اپلیکیشنهای سنگین از نظر UI مشکل بزرگی ایجاد میکند. هنگامی که یک وظیفه طولانیمدت، مانند پردازش دادههای پیچیده، محاسبات سنگین یا دستکاری گسترده DOM، رشته اصلی را اشغال میکند، از اجرای سایر عملیاتهای حیاتی جلوگیری میکند. این عملیاتهای مسدود شده عبارتند از:
- پاسخ به ورودی کاربر (کلیک، تایپ، اسکرول)
- اجرای انیمیشنها
- اجرای سایر وظایف جاوا اسکریپت، از جمله بهروزرسانیهای UI
- مدیریت درخواستهای شبکه
نتیجه این رفتار مسدودکننده، تجربه کاربری ضعیف است. کاربران ممکن است با یک رابط کاربری فریز شده، پاسخهای تأخیری یا انیمیشنهای بریدهبریده مواجه شوند که منجر به ناامیدی و ترک اپلیکیشن میشود. این مشکل اغلب به عنوان «مشکل مسدودسازی» (blocking problem) شناخته میشود.
محدودیتهای رندرینگ همزمان سنتی
در دوران پیش از React همزمان (pre-concurrent React)، بهروزرسانیهای رندرینگ معمولاً همزمان بودند. هنگامی که state یا props یک کامپوننت تغییر میکرد، React بلافاصله آن کامپوننت و فرزندانش را دوباره رندر میکرد. اگر این فرآیند رندر مجدد شامل حجم قابل توجهی از کار بود، میتوانست رشته اصلی را مسدود کند و منجر به مشکلات عملکردی ذکر شده شود. تصور کنید یک عملیات رندرینگ لیست پیچیده یا یک تجسم داده متراکم که صدها میلیثانیه طول میکشد تا کامل شود. در این مدت، تعامل کاربر نادیده گرفته میشد و یک اپلیکیشن غیرواکنشگرا ایجاد میکرد.
چرا چندوظیفگی مشارکتی راهحل است
چندوظیفگی مشارکتی سیستمی است که در آن وظایف به طور داوطلبانه کنترل CPU را به وظایف دیگر واگذار میکنند. برخلاف چندوظیفگی انحصاری (preemptive multitasking) (که در سیستمعاملها استفاده میشود، جایی که سیستمعامل میتواند یک وظیفه را در هر زمان قطع کند)، چندوظیفگی مشارکتی به خود وظایف متکی است تا تصمیم بگیرند چه زمانی متوقف شوند و به دیگران اجازه اجرا دهند. در زمینه جاوا اسکریپت و React، این بدان معناست که یک وظیفه رندرینگ طولانی میتواند به قطعات کوچکتر تقسیم شود و پس از تکمیل یک قطعه، میتواند کنترل را به حلقه رویداد (event loop) «واگذار» کند و به وظایف دیگر (مانند ورودی کاربر یا انیمیشنها) اجازه پردازش دهد. زمانبند React یک شکل پیچیده از چندوظیفگی مشارکتی را برای دستیابی به این هدف پیادهسازی میکند.
چندوظیفگی مشارکتی زمانبند React و نقش زمانبند
زمانبند React (React Scheduler) یک کتابخانه داخلی در React است که مسئول اولویتبندی و هماهنگی وظایف است. این موتور محرک ویژگیهای همزمان React 18 است. هدف اصلی آن اطمینان از واکنشگرا ماندن UI با زمانبندی هوشمندانه کار رندرینگ است. این کار را از طریق موارد زیر انجام میدهد:
- اولویتبندی: زمانبند به وظایف مختلف اولویت اختصاص میدهد. به عنوان مثال، یک تعامل فوری کاربر (مانند تایپ کردن در یک فیلد ورودی) اولویت بالاتری نسبت به واکشی داده در پسزمینه دارد.
- تقسیم کار: به جای انجام یک کار رندرینگ بزرگ به یکباره، زمانبند آن را به واحدهای کاری کوچکتر و مستقل تقسیم میکند.
- وقفه و ازسرگیری: زمانبند میتواند یک کار رندرینگ را در صورت در دسترس قرار گرفتن یک کار با اولویت بالاتر، قطع کرده و سپس کار قطع شده را بعداً از سر بگیرد.
- واگذاری وظیفه (Task Yielding): این مکانیسم اصلی است که امکان چندوظیفگی مشارکتی را فراهم میکند. پس از تکمیل یک واحد کوچک از کار، وظیفه میتواند کنترل را به زمانبند بازگرداند، که سپس تصمیم میگیرد چه کاری را در ادامه انجام دهد.
حلقه رویداد (Event Loop) و نحوه تعامل آن با زمانبند
درک حلقه رویداد جاوا اسکریپت برای فهمیدن نحوه عملکرد زمانبند بسیار مهم است. حلقه رویداد به طور مداوم یک صف پیام را بررسی میکند. هنگامی که یک پیام (که نماینده یک رویداد یا یک وظیفه است) پیدا میشود، پردازش میشود. اگر پردازش یک وظیفه (مثلاً یک رندر React) طولانی باشد، میتواند حلقه رویداد را مسدود کرده و از پردازش پیامهای دیگر جلوگیری کند. زمانبند React در هماهنگی با حلقه رویداد کار میکند. هنگامی که یک کار رندرینگ تقسیم میشود، هر زیروظیفه پردازش میشود. اگر یک زیروظیفه تکمیل شود، زمانبند میتواند از مرورگر بخواهد که زیروظیفه بعدی را در زمان مناسبی اجرا کند، اغلب پس از پایان تیک فعلی حلقه رویداد، اما قبل از اینکه مرورگر نیاز به نقاشی صفحه داشته باشد. این امر به سایر رویدادهای موجود در صف اجازه میدهد تا در این فاصله پردازش شوند.
توضیح رندرینگ همزمان (Concurrent Rendering)
رندرینگ همزمان، توانایی React برای رندر کردن چندین کامپوننت به صورت موازی یا قطع کردن رندرینگ است. این به معنای اجرای چندین رشته نیست؛ بلکه به معنای مدیریت مؤثرتر یک رشته واحد است. با رندرینگ همزمان:
- React میتواند شروع به رندر کردن یک درخت کامپوننت کند.
- اگر یک بهروزرسانی با اولویت بالاتر رخ دهد (مثلاً کاربر روی دکمه دیگری کلیک کند)، React میتواند رندرینگ فعلی را متوقف کرده، بهروزرسانی جدید را مدیریت کند و سپس رندرینگ قبلی را از سر بگیرد.
- این کار از فریز شدن UI جلوگیری میکند و تضمین میکند که تعاملات کاربر همیشه به سرعت پردازش میشوند.
زمانبند، هماهنگکننده این همزمانی است. این تصمیم میگیرد که چه زمانی رندر کند، چه زمانی متوقف شود و چه زمانی از سر بگیرد، همه اینها بر اساس اولویتها و «برشهای زمانی» موجود است.
استراتژی واگذاری وظیفه: قلب چندوظیفگی مشارکتی
استراتژی واگذاری وظیفه، مکانیزمی است که به وسیله آن یک وظیفه جاوا اسکریپت، به ویژه یک وظیفه رندرینگ مدیریت شده توسط زمانبند React، به طور داوطلبانه کنترل را واگذار میکند. این سنگ بنای چندوظیفگی مشارکتی در این زمینه است. هنگامی که React در حال انجام یک عملیات رندرینگ بالقوه طولانی است، آن را در یک بلوک یکپارچه انجام نمیدهد. در عوض، کار را به واحدهای کوچکتر تقسیم میکند. پس از تکمیل هر واحد، بررسی میکند که آیا «زمان» برای ادامه دادن دارد یا باید متوقف شود و به وظایف دیگر اجازه اجرا دهد. این بررسی جایی است که واگذاری وارد عمل میشود.
نحوه عملکرد واگذاری در پشت صحنه
در سطح بالا، هنگامی که زمانبند React در حال پردازش یک رندر است، ممکن است یک واحد کار را انجام دهد، سپس یک شرط را بررسی کند. این شرط اغلب شامل پرسوجو از مرورگر در مورد اینکه چقدر زمان از رندر شدن فریم قبلی گذشته است یا اینکه آیا بهروزرسانیهای فوری رخ داده است، میشود. اگر برش زمانی اختصاص داده شده برای وظیفه فعلی تمام شده باشد، یا اگر یک وظیفه با اولویت بالاتر در انتظار باشد، زمانبند واگذار خواهد کرد.
در محیطهای قدیمیتر جاوا اسکریپت، این ممکن بود با استفاده از `setTimeout(..., 0)` یا `requestIdleCallback` انجام شود. زمانبند React از مکانیزمهای پیچیدهتری، اغلب با استفاده از `requestAnimationFrame` و زمانبندی دقیق، برای واگذاری و ازسرگیری کار به طور کارآمد استفاده میکند، بدون اینکه لزوماً کنترل را به حلقه رویداد اصلی مرورگر به گونهای بازگرداند که پیشرفت را کاملاً متوقف کند. این میتواند قطعه بعدی کار را برای اجرا در فریم انیمیشن بعدی موجود یا در یک لحظه بیکاری زمانبندی کند.
تابع `shouldYield` (مفهومی)
اگرچه توسعهدهندگان مستقیماً تابع `shouldYield()` را در کد اپلیکیشن خود فراخوانی نمیکنند، اما این یک نمایش مفهومی از فرآیند تصمیمگیری در داخل زمانبند است. پس از انجام یک واحد کار (مثلاً رندر کردن بخش کوچکی از یک درخت کامپوننت)، زمانبند به صورت داخلی میپرسد: «آیا باید اکنون واگذار کنم؟» این تصمیم بر اساس موارد زیر است:
- برشهای زمانی: آیا وظیفه فعلی از بودجه زمانی اختصاص داده شده خود برای این فریم فراتر رفته است؟
- اولویت وظیفه: آیا وظایف با اولویت بالاتری در انتظار هستند که نیاز به توجه فوری دارند؟
- وضعیت مرورگر: آیا مرورگر با سایر عملیاتهای حیاتی مانند نقاشی مشغول است؟
اگر پاسخ به هر یک از این سؤالات «بله» باشد، زمانبند واگذار خواهد کرد. این بدان معناست که کار رندرینگ فعلی را متوقف میکند، به وظایف دیگر (از جمله بهروزرسانیهای UI یا مدیریت رویداد کاربر) اجازه اجرا میدهد و سپس، در زمان مناسب، کار رندرینگ قطع شده را از جایی که متوقف شده بود، از سر میگیرد.
مزیت: بهروزرسانیهای UI بدون مسدودسازی
مزیت اصلی استراتژی واگذاری وظیفه، توانایی انجام بهروزرسانیهای UI بدون مسدود کردن رشته اصلی است. این امر منجر به موارد زیر میشود:
- اپلیکیشنهای واکنشگرا: UI حتی در حین عملیات رندرینگ پیچیده، تعاملی باقی میماند. کاربران میتوانند بدون تجربه تأخیر، روی دکمهها کلیک کنند، اسکرول کنند و تایپ کنند.
- انیمیشنهای روانتر: انیمیشنها کمتر دچار لکنت یا افت فریم میشوند زیرا رشته اصلی به طور مداوم مسدود نمیشود.
- عملکرد درک شده بهبود یافته: حتی اگر یک عملیات در مجموع همان مقدار زمان را بگیرد، تقسیم آن و واگذاری باعث میشود اپلیکیشن *احساس* سریعتر و واکنشگراتری داشته باشد.
پیامدهای عملی و نحوه بهرهبرداری از واگذاری وظیفه
به عنوان یک توسعهدهنده React، شما معمولاً دستورات صریح `yield` را نمینویسید. زمانبند React این کار را به طور خودکار زمانی که از React 18+ استفاده میکنید و ویژگیهای همزمان آن فعال هستند، مدیریت میکند. با این حال، درک این مفهوم به شما امکان میدهد کدی بنویسید که در این مدل بهتر رفتار کند.
واگذاری خودکار با حالت همزمان
هنگامی که شما رندرینگ همزمان را انتخاب میکنید (با استفاده از React 18+ و پیکربندی مناسب `ReactDOM` خود)، زمانبند React کنترل را به دست میگیرد. این به طور خودکار کار رندرینگ را تقسیم کرده و در صورت لزوم واگذار میکند. این بدان معناست که بسیاری از دستاوردهای عملکردی از چندوظیفگی مشارکتی به صورت آماده در دسترس شما هستند.
شناسایی وظایف رندرینگ طولانیمدت
در حالی که واگذاری خودکار قدرتمند است، هنوز هم مفید است که از آنچه *میتواند* باعث وظایف طولانیمدت شود، آگاه باشید. این موارد اغلب شامل:
- رندر کردن لیستهای بزرگ: هزاران آیتم میتوانند زمان زیادی برای رندر شدن بگیرند.
- رندرینگ شرطی پیچیده: منطق شرطی عمیقاً تودرتو که منجر به ایجاد یا تخریب تعداد زیادی گره DOM میشود.
- محاسبات سنگین در توابع رندر: انجام محاسبات گرانقیمت مستقیماً در داخل متد رندر یک کامپوننت.
- بهروزرسانیهای state مکرر و بزرگ: تغییر سریع مقادیر زیادی از داده که باعث رندرهای مجدد گسترده میشود.
استراتژیهایی برای بهینهسازی و کار با واگذاری
در حالی که React واگذاری را مدیریت میکند، شما میتوانید کامپوننتهای خود را به روشهایی بنویسید که بیشترین بهره را از آن ببرند:
- مجازیسازی (Virtualization) برای لیستهای بزرگ: برای لیستهای بسیار طولانی، از کتابخانههایی مانند `react-window` یا `react-virtualized` استفاده کنید. این کتابخانهها فقط آیتمهایی را که در حال حاضر در viewport قابل مشاهده هستند رندر میکنند و به طور قابل توجهی میزان کاری را که React در هر زمان باید انجام دهد کاهش میدهند. این به طور طبیعی منجر به فرصتهای واگذاری مکررتر میشود.
- مموسازی (Memoization) (`React.memo`, `useMemo`, `useCallback`): اطمینان حاصل کنید که کامپوننتها و مقادیر شما فقط در صورت لزوم دوباره محاسبه میشوند. `React.memo` از رندرهای مجدد غیرضروری کامپوننتهای تابعی جلوگیری میکند. `useMemo` محاسبات گرانقیمت را کش میکند و `useCallback` تعاریف تابع را کش میکند. این کار میزان کاری را که React باید انجام دهد کاهش میدهد و واگذاری را مؤثرتر میکند.
- تقسیم کد (Code Splitting) (`React.lazy` و `Suspense`): اپلیکیشن خود را به قطعات کوچکتری تقسیم کنید که بر اساس تقاضا بارگذاری میشوند. این کار بار رندرینگ اولیه را کاهش میدهد و به React اجازه میدهد تا بر روی رندر کردن بخشهای مورد نیاز فعلی UI تمرکز کند.
- Debouncing و Throttling ورودی کاربر: برای فیلدهای ورودی که عملیات گرانقیمتی را فعال میکنند (مانند پیشنهادات جستجو)، از debouncing یا throttling برای محدود کردن تعداد دفعات انجام عملیات استفاده کنید. این کار از سیل بهروزرسانیهایی که میتواند زمانبند را تحت فشار قرار دهد، جلوگیری میکند.
- انتقال محاسبات گرانقیمت به خارج از رندر: اگر وظایف محاسباتی سنگینی دارید، آنها را به event handlerها، هوکهای `useEffect` یا حتی web workerها منتقل کنید. این کار تضمین میکند که خود فرآیند رندرینگ تا حد امکان سبک نگه داشته شود و امکان واگذاری مکررتر را فراهم میکند.
- دستهبندی بهروزرسانیها (خودکار و دستی): React 18 به طور خودکار بهروزرسانیهای state را که در event handlerها یا Promiseها رخ میدهند، دستهبندی میکند. اگر نیاز به دستهبندی دستی بهروزرسانیها در خارج از این زمینهها دارید، میتوانید از `ReactDOM.flushSync()` برای سناریوهای خاصی که بهروزرسانیهای فوری و همزمان حیاتی هستند، استفاده کنید، اما از این کار به ندرت استفاده کنید زیرا رفتار واگذاری زمانبند را دور میزند.
مثال: بهینهسازی یک جدول داده بزرگ
اپلیکیشنی را در نظر بگیرید که یک جدول بزرگ از دادههای سهام بینالمللی را نمایش میدهد. بدون همزمانی و واگذاری، رندر کردن 10,000 ردیف ممکن است UI را برای چندین ثانیه فریز کند.
بدون واگذاری (مفهومی):
یک تابع `renderTable` واحد در تمام 10,000 ردیف پیمایش میکند، برای هر کدام عناصر `
با واگذاری (با استفاده از React 18+ و بهترین شیوهها):
- مجازیسازی: از کتابخانهای مانند `react-window` استفاده کنید. کامپوننت جدول فقط، مثلاً، 20 ردیف قابل مشاهده در viewport را رندر میکند.
- نقش زمانبند: هنگامی که کاربر اسکرول میکند، مجموعه جدیدی از ردیفها قابل مشاهده میشود. زمانبند React رندرینگ این ردیفهای جدید را به قطعات کوچکتر تقسیم میکند.
- واگذاری وظیفه در عمل: همانطور که هر قطعه کوچک از ردیفها رندر میشود (مثلاً هر بار 2-5 ردیف)، زمانبند بررسی میکند که آیا باید واگذار کند. اگر کاربر به سرعت اسکرول کند، React ممکن است پس از رندر کردن چند ردیف واگذار کند، و به رویداد اسکرول اجازه پردازش دهد و مجموعه بعدی ردیفها برای رندرینگ زمانبندی شود. این تضمین میکند که رویداد اسکرول روان و واکنشگرا احساس شود، حتی اگر کل جدول به یکباره رندر نشده باشد.
- مموسازی: کامپوننتهای ردیفهای فردی میتوانند ممو شوند (`React.memo`) تا اگر فقط یک ردیف نیاز به بهروزرسانی داشته باشد، بقیه دوباره رندر نشوند.
نتیجه یک تجربه اسکرول روان و یک UI است که تعاملی باقی میماند و قدرت چندوظیفگی مشارکتی و واگذاری وظیفه را نشان میدهد.
ملاحظات جهانی و مسیرهای آینده
اصول چندوظیفگی مشارکتی و واگذاری وظیفه به طور جهانی قابل اجرا هستند، صرف نظر از مکان کاربر یا قابلیتهای دستگاه. با این حال، برخی ملاحظات جهانی وجود دارد:
- عملکرد متفاوت دستگاهها: کاربران در سراسر جهان به اپلیکیشنهای وب بر روی طیف گستردهای از دستگاهها، از دسکتاپهای پیشرفته تا تلفنهای همراه کمقدرت، دسترسی دارند. چندوظیفگی مشارکتی تضمین میکند که اپلیکیشنها حتی بر روی دستگاههای کمقدرتتر نیز میتوانند واکنشگرا باقی بمانند، زیرا کار تقسیم شده و به طور کارآمدتری به اشتراک گذاشته میشود.
- تأخیر شبکه: در حالی که واگذاری وظیفه عمدتاً به وظایف رندرینگ وابسته به CPU میپردازد، توانایی آن در رفع انسداد UI برای اپلیکیشنهایی که به طور مکرر دادهها را از سرورهای توزیع شده جغرافیایی واکشی میکنند نیز حیاتی است. یک UI واکنشگرا میتواند بازخورد (مانند اسپینرهای بارگذاری) را در حین انجام درخواستهای شبکه ارائه دهد، به جای اینکه فریز شده به نظر برسد.
- دسترسپذیری (Accessibility): یک UI واکنشگرا ذاتاً قابل دسترستر است. کاربرانی که دارای اختلالات حرکتی هستند و ممکن است زمانبندی دقیقتری برای تعاملات نداشته باشند، از اپلیکیشنی که فریز نمیشود و ورودی آنها را نادیده نمیگیرد، سود خواهند برد.
تکامل زمانبند React
زمانبند React یک قطعه فناوری در حال تکامل مداوم است. مفاهیم اولویتبندی، زمانهای انقضا و واگذاری پیچیده هستند و در طول تکرارهای زیادی اصلاح شدهاند. تحولات آینده در React احتمالاً قابلیتهای زمانبندی آن را بیشتر تقویت خواهد کرد و به طور بالقوه راههای جدیدی را برای بهرهبرداری از APIهای مرورگر یا بهینهسازی توزیع کار کاوش خواهد کرد. حرکت به سمت ویژگیهای همزمان، گواهی بر تعهد React به حل چالشهای عملکردی پیچیده برای اپلیکیشنهای وب جهانی است.
نتیجهگیری
چندوظیفگی مشارکتی زمانبند React، که توسط استراتژی واگذاری وظیفه آن قدرت میگیرد، پیشرفت قابل توجهی در ساخت اپلیکیشنهای وب با عملکرد بالا و واکنشگرا است. با تقسیم وظایف رندرینگ بزرگ و اجازه دادن به کامپوننتها برای واگذاری داوطلبانه کنترل، React تضمین میکند که UI حتی تحت بار سنگین، تعاملی و روان باقی بماند. درک این استراتژی به توسعهدهندگان قدرت میدهد تا کد کارآمدتری بنویسند، از ویژگیهای همزمان React به طور مؤثر استفاده کنند و تجربیات کاربری استثنایی را به مخاطبان جهانی ارائه دهند.
در حالی که نیازی به مدیریت دستی واگذاری ندارید، آگاهی از مکانیسمهای آن به بهینهسازی کامپوننتها و معماری شما کمک میکند. با پذیرش شیوههایی مانند مجازیسازی، مموسازی و تقسیم کد، میتوانید از پتانسیل کامل زمانبند React بهرهمند شوید و اپلیکیشنهایی ایجاد کنید که نه تنها کاربردی، بلکه استفاده از آنها نیز لذتبخش باشد، صرف نظر از اینکه کاربران شما در کجا قرار دارند.
آینده توسعه React همزمان است و تسلط بر اصول اساسی چندوظیفگی مشارکتی و واگذاری وظیفه، کلید باقی ماندن در خط مقدم عملکرد وب است.