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

جاوا اسکریپت اغلب باعث ایجاد تغییرات بصری می شود. گاهی اوقات این به طور مستقیم از طریق دستکاری سبک انجام می شود، و گاهی اوقات این محاسبات است که منجر به تغییرات بصری، مانند جستجو یا مرتب سازی داده ها می شود. جاوا اسکریپت بد زمان یا طولانی مدت یکی از دلایل رایج مشکلات عملکرد است. شما باید به دنبال به حداقل رساندن تأثیر آن در جایی که می توانید باشید.

جاوا اسکریپت اغلب باعث ایجاد تغییرات بصری می شود. گاهی اوقات این به طور مستقیم از طریق دستکاری سبک انجام می شود، و گاهی اوقات این محاسبات است که منجر به تغییرات بصری، مانند جستجو یا مرتب سازی داده ها می شود. جاوا اسکریپت بد زمان یا طولانی مدت یکی از دلایل رایج مشکلات عملکرد است. شما باید به دنبال به حداقل رساندن تأثیر آن در جایی که می توانید باشید.

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

با همه آنچه گفته شد، مواردی وجود دارد که قطعاً می توانید انجام دهید تا به برنامه های خود کمک کنید جاوا اسکریپت را به خوبی اجرا کنند.

خلاصه

  • از setTimeout یا setInterval برای به‌روزرسانی‌های بصری اجتناب کنید. همیشه به جای آن از requestAnimationFrame استفاده کنید.
  • جاوا اسکریپت طولانی مدت را از موضوع اصلی به Web Workers منتقل کنید.
  • برای ایجاد تغییرات DOM در چندین فریم از وظایف میکرو استفاده کنید.
  • برای ارزیابی تأثیر جاوا اسکریپت از جدول زمانی Chrome DevTools و نمایه JavaScript استفاده کنید.

برای تغییرات بصری از requestAnimationFrame استفاده کنید

هنگامی که تغییرات بصری روی صفحه رخ می دهد، می خواهید کار خود را در زمان مناسب برای مرورگر انجام دهید، که درست در ابتدای کادر است. تنها راه برای تضمین اجرای جاوا اسکریپت شما در شروع یک فریم، استفاده از requestAnimationFrame است.

/**
    * If run as a requestAnimationFrame callback, this
    * will be run at the start of the frame.
    */
function updateScreen(time) {
    // Make visual updates here.
}

requestAnimationFrame(updateScreen);

فریم‌ورک‌ها یا نمونه‌ها ممکن است از setTimeout یا setInterval برای انجام تغییرات بصری مانند انیمیشن‌ها استفاده کنند، اما مشکل این است که تماس برگشتی در نقطه‌ای از کادر اجرا می‌شود، احتمالاً درست در پایان، و این اغلب می‌تواند باعث شود از دست دادن یک فریم، در نتیجه jank.

setTimeout باعث می شود مرورگر یک فریم را از دست بدهد.

در واقع، جی کوئری از setTimeout برای رفتار animate خود استفاده می کرد. برای استفاده از requestAnimationFrame در نسخه 3 تغییر کرد. اگر از نسخه قدیمی jQuery استفاده می کنید، می توانید آن را برای استفاده از requestAnimationFrame وصله کنید ، که اکیداً توصیه می شود.

پیچیدگی را کاهش دهید یا از Web Workers استفاده کنید

جاوا اسکریپت روی رشته اصلی مرورگر، درست در کنار محاسبات سبک، طرح‌بندی، و در بسیاری موارد، رنگ اجرا می‌شود. اگر جاوا اسکریپت شما برای مدت طولانی اجرا شود، این وظایف دیگر را مسدود می کند و به طور بالقوه باعث از دست رفتن فریم ها می شود.

شما باید در مورد زمان اجرای جاوا اسکریپت و مدت زمان تاکتیکی باشید. به عنوان مثال، اگر در انیمیشنی مانند اسکرول هستید، در حالت ایده آل باید به دنبال حفظ جاوا اسکریپت خود در محدوده 3-4 میلی ثانیه باشید. بیشتر از آن و شما در معرض خطر گرفتن زمان زیادی هستید. اگر در دوره بیکاری هستید، می توانید در مورد زمان صرف شده آرامش بیشتری داشته باشید.

در بسیاری از موارد می‌توانید کار محاسباتی خالص را به Web Workers منتقل کنید، برای مثال اگر به دسترسی DOM نیاز نداشته باشد. دستکاری یا پیمایش داده‌ها، مانند مرتب‌سازی یا جستجو، اغلب برای این مدل مناسب هستند، مانند بارگذاری و تولید مدل.

var dataSortWorker = new Worker("sort-worker.js");
dataSortWorker.postMesssage(dataToSort);

// The main thread is now free to continue working on other things...

dataSortWorker.addEventListener('message', function(evt) {
    var sortedData = evt.data;
    // Update data on screen...
});

همه کارها نمی توانند با این مدل مطابقت داشته باشند: Web Workers دسترسی DOM ندارند. جایی که کار شما باید در موضوع اصلی باشد، یک رویکرد دسته‌بندی را در نظر بگیرید، که در آن کار بزرگ‌تر را به وظایف کوچک تقسیم می‌کنید، که هر کدام بیش از چند میلی‌ثانیه طول نمی‌کشد، و در داخل دسته‌های requestAnimationFrame در هر فریم اجرا می‌شوند.

پیامدهای UX و UI برای این رویکرد وجود دارد، و شما باید مطمئن شوید که کاربر می‌داند که یک کار در حال پردازش است، چه با استفاده از نشانگر پیشرفت یا فعالیت . در هر صورت این رویکرد رشته اصلی برنامه شما را آزاد نگه می دارد و به آن کمک می کند تا به تعاملات کاربر پاسخگو بماند.

"مالیات فریم" جاوا اسکریپت خود را بدانید

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

پانل عملکرد کروم DevTools بهترین راه برای اندازه گیری هزینه جاوا اسکریپت شماست. معمولاً شما رکوردهای سطح پایینی مانند زیر دریافت می کنید:

ضبط عملکرد در Chrome DevTools

بخش اصلی نمودار شعله ای از فراخوانی های جاوا اسکریپت را ارائه می دهد تا بتوانید دقیقاً کدام توابع فراخوانی شده اند و هر کدام چقدر طول کشیده است.

با استفاده از این اطلاعات می توانید تأثیر عملکرد جاوا اسکریپت را بر برنامه خود ارزیابی کنید و شروع به یافتن و رفع نقاط مهمی کنید که در آن عملکردها بیش از حد طول می کشد تا اجرا شوند. همانطور که قبلا ذکر شد، باید به دنبال حذف جاوا اسکریپت طولانی مدت باشید، یا اگر این امکان وجود ندارد، آن را به یک Web Worker انتقال دهید تا رشته اصلی را آزاد کنید تا به کارهای دیگر ادامه دهید.

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

از بهینه سازی میکرو جاوا اسکریپت خودداری کنید

شاید جالب باشد که بدانید مرورگر می تواند یک نسخه از یک چیز را 100 برابر سریعتر از چیز دیگر اجرا کند، مانند اینکه درخواست offsetTop یک عنصر سریعتر از محاسبه getBoundingClientRect() است، اما تقریبا همیشه درست است که شما فقط توابع را فراخوانی می کنید. مانند این تعداد دفعات کمی در هر فریم، بنابراین معمولاً تلاش برای تمرکز بر این جنبه از عملکرد جاوا اسکریپت بیهوده است. شما معمولاً فقط در کسری از میلی ثانیه صرفه جویی می کنید.

اگر در حال ساخت یک بازی یا یک برنامه گران قیمت محاسباتی هستید، احتمالاً یک استثنا برای این راهنمایی هستید، زیرا معمولاً محاسبات زیادی را در یک فریم قرار می دهید، و در این صورت همه چیز کمک می کند.

به طور خلاصه، شما باید در مورد بهینه سازی های کوچک بسیار محتاط باشید، زیرا آنها معمولاً با نوع برنامه ای که می سازید، مطابقت ندارند.