مقدمه

عملکرد یا پرفورمنس، یک ویژگی جانبی نیست، بلکه یکی از مهم‌ترین جنبه‌های تجربه کاربری (UX) است. یک وب‌سایت یا اپلیکیشن کند، کاربران را خسته و ناامید می‌کند و می‌تواند مستقیماً بر روی معیارهای کسب‌وکار مانند نرخ تبدیل (conversion rate) و تعامل کاربر (engagement) تأثیر منفی بگذارد. بهینه‌سازی عملکرد به معنی کاهش زمان بارگذاری، افزایش سرعت پاسخ‌دهی به تعاملات کاربر، و ایجاد یک تجربه روان و لذت‌بخش است. در این درس به بررسی تکنیک‌های کلیدی برای بهبود عملکرد در سه حوزه اصلی می‌پردازیم: تعامل با DOM، درخواست‌های شبکه، و اجرای کدهای جاوااسکریپت.

بهینه‌سازی تعامل با DOM

دستکاری DOM یکی از پرهزینه‌ترین عملیات‌ها در جاوااسکریپت سمت کلاینت است. هر تغییری در ساختار یا استایل DOM می‌تواند مرورگر را مجبور به انجام دو عملیات سنگین کند: `reflow` (محاسبه مجدد طرح‌بندی و موقعیت عناصر) و `repaint` (ترسیم مجدد پیکسل‌ها روی صفحه).

دسته‌بندی تغییرات DOM

به جای اعمال چندین تغییر مجزا روی DOM، آنها را در حافظه دسته‌بندی کرده و سپس یک‌جا به DOM اضافه کنید. همانطور که در درس‌های قبل دیدیم، استفاده از یک DocumentFragment برای این کار یک الگوی عالی است. با این روش، شما تنها یک عملیات `reflow` و `repaint` را به مرورگر تحمیل می‌کنید.

پرهیز از Layout Thrashing

یک اشتباه رایج که عملکرد را به شدت تحت تأثیر قرار می‌دهد، "Layout Thrashing" است. این اتفاق زمانی می‌افتد که شما در یک حلقه، به صورت متناوب مقادیر طرح‌بندی را از DOM می‌خوانید (مانند `element.offsetHeight`) و سپس مقادیری را در DOM می‌نویسید (مانند `element.style.height`). این کار مرورگر را مجبور می‌کند تا در هر بار تکرار حلقه، طرح‌بندی را مجدداً محاسبه کند.

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

بهینه‌سازی درخواست‌های شبکه

سرعت بارگذاری اولیه یک صفحه، به شدت به حجم و تعداد درخواست‌های شبکه بستگی دارد.

کاهش حجم فایل‌ها (Minification)

فایل‌های جاوااسکریپت و CSS شما باید قبل از استقرار در محیط پروداکشن، «کوچک‌سازی» یا minified شوند. این فرآیند که توسط باندلرها (مانند Vite و Webpack) به صورت خودکار انجام می‌شود، تمام فضاهای خالی، کامنت‌ها و نام‌های طولانی متغیرها را حذف کرده و حجم فایل را به شکل چشمگیری کاهش می‌دهد. همچنین فعال‌سازی فشرده‌سازی Gzip یا Brotli روی سرور نیز ضروری است.

تقسیم کد (Code Splitting)

به جای ارسال یک فایل جاوااسکریپت غول‌پیکر به کاربر، از تکنیک «تقسیم کد» استفاده کنید. باندلرها می‌توانند کد شما را به قطعات کوچک‌تر تقسیم کنند. قطعه اصلی فقط شامل کدهای ضروری برای بارگذاری اولیه صفحه است و قطعات دیگر (مثلاً کد مربوط به یک صفحه دیگر یا یک مدال خاص) تنها زمانی که به آنها نیاز باشد، به صورت پویا بارگذاری می‌شوند.

بارگذاری تنبل (Lazy Loading)

این تکنیک نه تنها برای کد، بلکه برای محتوا نیز کاربرد دارد. تصاویری که در قسمت پایینی صفحه قرار دارند و در دید اولیه کاربر نیستند، نباید در بارگذاری اولیه دانلود شوند. با استفاده از IntersectionObserver API، می‌توانیم دانلود آنها را تا زمانی که کاربر به نزدیکی آنها اسکرول کند، به تعویق بیندازیم.

بهینه‌سازی اجرای جاوااسکریپت

نحوه نوشتن و اجرای کدهای جاوااسکریپت نیز تأثیر مستقیمی بر عملکرد دارد.

الگوهای Debounce و Throttle

برخی رویدادها مانند scroll، resize یا input می‌توانند در مدت زمان کوتاهی صدها بار اجرا شوند. اگر شنونده رویداد شما یک عملیات سنگین انجام دهد، این کار به راحتی باعث کندی و لگ در رابط کاربری می‌شود. برای کنترل این وضعیت از دو الگوی رایج استفاده می‌شود:

  • Debounce: اجرای تابع را تا زمانی که یک دوره زمانی مشخصی از سکون بگذرد، به تعویق می‌اندازد. اگر در این مدت رویداد دوباره تکرار شود، تایمر ریست می‌شود. این الگو برای مواردی مانند جستجوی خودکار پس از تایپ کاربر ایده‌آل است.
  • Throttle: تضمین می‌کند که یک تابع در یک بازه زمانی مشخص، حداکثر یک بار اجرا شود. این الگو برای مواردی مانند مدیریت انیمیشن‌ها در حین اسکرول کردن مناسب است.
Copy Icon JAVASCRIPT - Debounce Example
function debounce(func, delay) {
    let timeoutId;
    return function(...args) {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => {
            func.apply(this, args);
        }, delay);
    };
}
// Usage: searchInput.addEventListener('input', debounce(handleSearch, 300));
Copy Icon JAVASCRIPT - Throttle Example
function throttle(func, limit) {
    let inThrottle;
    return function(...args) {
        if (!inThrottle) {
            func.apply(this, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}
// Usage: window.addEventListener('scroll', throttle(handleScroll, 100));

در این درس با تکنیک‌های مختلفی برای بهبود عملکرد اپلیکیشن‌های وب آشنا شدیم. از بهینه‌سازی تعامل با DOM و درخواست‌های شبکه گرفته تا الگوهای پیشرفته‌ای مانند debounce و throttle برای مدیریت رویدادها. این توصیه‌ها به شما کمک می‌کنند تا تجربه‌ی کاربری سریع، روان و لذت‌بخشی را برای کاربران خود فراهم کنید. در درس پایانی این فصل و بخش جاوااسکریپت سمت کاربر، به «توصیه‌های مربوط به Deployment» خواهیم پرداخت و مراحل نهایی آماده‌سازی و استقرار یک پروژه وب را بررسی خواهیم کرد.