Frontend Development

بهینه‌سازی TTFB و کاهش کارهای رشته اصلی

عملکرد وب دیگر تنها یک ویژگی «خوب است که داشته باشیم» نیست؛ بلکه عاملی حیاتی برای حفظ کاربران، رتبه‌بندی در موتورهای جستجو و موفقیت کلی برنامه است. در میان معیارهای مختلف هسته وب (Core Web Vitals) و شاخص‌های عملکرد، دو مورد به عنوان موانع بنیادی برای ایجاد یک تجربه کاربری سریع و واکنش‌گرا برجسته هستند: زمان تا اولین بایت (TTFB) و مسدود شدن رشته اصلی. در این راهنما، استراتژی‌های عملی برای کاهش TTFB و آزاد نگه داشتن رشته اصلی جاوااسکریپت برای تعاملات واکنش‌گرا را بررسی خواهیم کرد.

درک و کاهش TTFB

TTFB زمانی را اندازه‌گیری می‌کند که بین درخواست کاربر برای یک صفحه و لحظه‌ای که مرورگر اولین بایت داده‌ها را از سرور دریافت می‌کند، سپری می‌شود. اگرچه این شاخص از نظر فنی شامل تأخیر شبکه و زمان پردازش سرور است، اما توسعه‌دهندگان فرانت‌اند کنترل قابل توجهی بر سرعت پاسخگویی سرور دارند. یک TTFB بالا اغلب نشان می‌دهد که سرور زمان زیادی را صرف رندر کردن HTML یا دریافت داده‌ها قبل از ارسال هرگونه پاسخ می‌کند.

۱. استفاده از کش لبه (Edge Caching) و شبکه‌های تحویل محتوا (CDN)

موثرترین راه برای کاهش TTFB، ارائه محتوای ایستا از سرورهایی است که از نظر جغرافیایی به کاربر نزدیک‌تر هستند. استفاده از یک شبکه تحویل محتوا (CDN) دارایی‌های شما و حتی پاسخ‌های HTML ایستا را در مکان‌های لبه (edge locations) کش می‌کند. برای محتوای پویا، در نظر بگیرید که از محاسبات لبه (مانند Cloudflare Workers یا AWS Lambda@Edge) برای اجرای منطق سبک‌تر نزدیک‌تر به کاربر استفاده کنید تا کاملاً از سرور مبدأ دور شوید.

۲. بهینه‌سازی رندر سمت سرور (SSR)

اگر از چارچوب‌هایی مانند Next.js، Nuxt یا Remix استفاده می‌کنید، مطمئن شوید که سرور شما توسط کوئری‌های ناکارآمد پایگاه داده یا منطق پیچیده سمت سرور در حین رندر اولیه گلوگاه ایجاد نمی‌کند. در صورت امکان، بازسازی ایستا افزایشی (ISR) را پیاده‌سازی کنید تا صفحات HTML از پیش رندر شده را به جای محاسبه آن‌ها در هر درخواست ارائه دهید.

به حداقل رساندن کارهای رشته اصلی

پس از دریافت HTML، رشته اصلی مرورگر کار را بر عهده می‌گیرد تا DOM را تجزیه، جاوااسکریپت را اجرا کند و چیدمان (layout) را محاسبه نماید. اگر این رشته توسط وظایف محاسباتی سنگین مسدود شود، برنامه کُند به نظر خواهد رسید و این امر منجر به نمرات ضعیف در Interaction to Next Paint (INP) و First Input Delay (FID) می‌شود.

۱. وظایف طولانی را به قطعات کوچکتر تقسیم کنید

جاوااسکریپت در محیط اصلی تک‌رشته‌ای است. یک وظیفه طولانی‌مدت، که معمولاً به عنوان اسکریپتی تعریف می‌شود که بیش از ۵۰ میلی‌ثانیه طول می‌کشد تا اجرا شود، می‌تواند رابط کاربری را فریز کند. برای جلوگیری از این اتفاق، می‌توانید محاسبات بزرگ را به قطعات کوچکتر با استفاده از setTimeout، requestIdleCallback یا با استفاده از Web Workers برای کارهای سنگین تقسیم کنید.

در اینجا نمونه‌ای از استفاده از setTimeout برای واگذاری کنترل به رشته اصلی بین پردازش آیتم‌ها آورده شده است:

function processLargeDataset(data) {
  let index = 0;
  const batchSize = 50; // پردازش ۵۰ آیتم در هر تیک

  function processBatch() {
    const end = Math.min(index + batchSize, data.length);
    
    for (; index < end; index++) {
      // انجام محاسبات در اینجا
      console.log('Processing item:', data[index]);
    }

    if (index < data.length) {
      // واگذاری به رشته اصلی قبل از دسته بعدی
      setTimeout(processBatch, 0);
    }
  }

  processBatch();
}

۲. جاوااسکریپت غیرحیاتی را به تعویق بیندازید و تأخیر دهید

همه جاوااسکریپت‌ها بلافاصله مورد نیاز نیستند. از ویژگی defer برای اسکریپت‌هایی استفاده کنید که مانع تجزیه HTML نمی‌شوند اما نیاز دارند پس از ساخته شدن DOM اجرا شوند. برای تحلیل‌ها یا سایر اسکریپت‌های شخص ثالث غیرضروری، از async استفاده کنید یا آن‌ها را به صورت پویا پس از بارگیری اولیه صفحه بارگذاری نمایید.

<!-- پس از تجزیه HTML بارگذاری می‌شود، ترتیب را حفظ می‌کند -->
<script src="app.js" defer></script>

<!-- به صورت ناهمگام بارگذاری می‌شود، ممکن است خارج از ترتیب اجرا شود -->
<script src="analytics.js" async></script>

۳. از Web Workers برای وظایف سنگین CPU استفاده کنید

برای وظایفی مانند پردازش تصویر، تجزیه داده‌های پیچیده یا محاسبات رمزنگاری، کار را به یک Web Worker واگذار کنید. این کار تضمین می‌کند که رشته اصلی برای ورودی‌های کاربر مانند کلیک‌ها و اسکرول‌ها واکنش‌گرا باقی بماند.

// main.js
const worker = new Worker('worker.js');

worker.postMessage(data);
worker.onmessage = function(e) {
  console.log('Result received:', e.data);
};

// worker.js
self.onmessage = function(e) {
  const result = heavyCalculation(e.data);
  self.postMessage(result);
};

نتیجه‌گیری

بهینه‌سازی TTFB و کارهای رشته اصلی نیازمند رویکردی کل‌نگر است که پیکربندی سرور، استراتژی‌های شبکه و معماری جاوااسکریپت سمت مشتری را در بر می‌گیرد. با پیاده‌سازی استراتژی‌های کش، تقسیم وظایف طولانی و واگذاری محاسبات سنگین، می‌توانید عملکرد ادراک‌شده برنامه‌های وب خود را به طور قابل توجهی بهبود بخشید. به یاد داشته باشید که عملکرد یک فرآیند مستمر است؛ به طور منظم شاخص‌های خود را با استفاده از ابزارهایی مانند Lighthouse یا Chrome DevTools بررسی کنید تا گلوگاه‌های جدید را همان‌طور که برنامه شما رشد می‌کند، شناسایی نمایید.

Share: