مقدمه
درک و اندازهگیری عملکرد (performance) کد، یکی از مهارتهای کلیدی برای توسعهدهندگان وب است.
توابع زمانبندی مانند setTimeout() برای اجرای کد در آینده مناسب
هستند، اما برای اندازهگیری دقیق مدت زمان اجرای یک عملیات، ابزار مناسبی نیستند. همچنین،
Date.now() که زمان را بر حسب میلیثانیه برمیگرداند، برای سنجش عملیاتهای بسیار سریع، دقت کافی
را ندارد.
برای حل این مشکل، مرورگرها Performance API را ارائه میدهند. این API یک ابزار استاندارد و با
دقت بسیار بالا (تا سطح میکروثانیه) برای اندازهگیری زمان و تحلیل عملکرد در اختیار ما قرار
میدهد. این API از طریق شیء سراسری performance قابل دسترسی است.
تایماستمپ با دقت بالا: performance.now()
سادهترین و سرراستترین ابزار در این API، متد performance.now()
است. این متد یک تایماستمپ با دقت بالا (DOMHighResTimeStamp) برمیگرداند که نشاندهنده تعداد
میلیثانیههایی است که از زمان شروع بارگذاری سند (timeOrigin) گذشته است.
برخلاف Date.now() که به ساعت سیستم وابسته است و ممکن است تغییر کند، مقدار بازگشتی از performance.now() همواره به صورت یکنواخت افزایش مییابد
(monotonically increasing) و آن را به گزینهای ایدهآل و قابل اعتماد برای اندازهگیری دقیق مدت
زمان بین دو نقطه در کد تبدیل میکند.
JAVASCRIPT
const startTime = performance.now();
for (let i = 0; i < 1000000; i++) {
Math.sqrt(i);
}
const endTime = performance.now();
const duration = endTime - startTime;
console.log(`The operation took ${duration.toFixed(3)} milliseconds.`);
در این مثال، ما زمان را قبل و بعد از یک حلقه سنگین ثبت کرده و با کم کردن آنها از یکدیگر، مدت
زمان دقیق اجرای حلقه را با دقت سه رقم اعشار به دست میآوریم. این دقت برای شناسایی تنگناهای
عملکردی (bottlenecks) بسیار مفید است.
نشانهگذاری و اندازهگیری با Marks و Measures
برای تحلیل عملکرد اپلیکیشنهای پیچیده که شامل چندین مرحله هستند، استفاده از تفاضل ساده performance.now() میتواند کد را شلوغ و مدیریت را سخت کند.
Performance API یک رویکرد ساختاریافتهتر با استفاده از «نشانگرها» (Marks) و «معیارها»
(Measures) ارائه میدهد. این ابزارها به ما اجازه میدهند تا نقاط مهمی از اجرای کد را نشانهگذاری
کرده و سپس فواصل زمانی بین این نقاط را اندازهگیری و تحلیل کنیم.
ایجاد نشانگر با performance.mark()
متد performance.mark(name) یک نشانگر زمان با نام مشخص در «بافر
عملکرد» (performance buffer) مرورگر ایجاد میکند. این کار مانند قرار دادن یک پرچم در یک نقطه خاص
از کد شماست تا بعداً بتوانید به آن لحظه زمانی ارجاع دهید.
ایجاد معیار با performance.measure()
متد performance.measure(name, startMark, endMark) مدت زمان بین دو
نشانگر را محاسبه کرده و نتیجه را با نام مشخص شده در بافر عملکرد ذخیره میکند.
JAVASCRIPT
performance.mark('app-start');
performance.mark('fetch-data-start');
performance.mark('fetch-data-end');
performance.mark('render-dom-start');
performance.mark('render-dom-end');
performance.measure('fetch-duration', 'fetch-data-start', 'fetch-data-end');
performance.measure('render-duration', 'render-dom-start', 'render-dom-end');
const allMeasures = performance.getEntriesByType('measure');
console.log(allMeasures);
allMeasures.forEach(measure => {
console.log(`${measure.name}: ${measure.duration.toFixed(2)}ms`);
});
performance.clearMarks();
performance.clearMeasures();
در این کد، ما نقاط شروع و پایان دو تسک فرضی (دریافت داده و رندر کردن) را نشانهگذاری میکنیم.
سپس با performance.measure()، مدت زمان هر کدام را محاسبه و ذخیره
میکنیم. در نهایت، با performance.getEntriesByType('measure') به
تمام معیارهای ثبت شده دسترسی پیدا کرده و آنها را نمایش میدهیم. این رویکرد ساختاریافته، تحلیل
پروفایل عملکرد اپلیکیشن را بسیار سادهتر میکند.
در این درس با `APIهای Timing` و روشهای استاندارد و دقیق برای سنجش عملکرد کدهایمان آشنا شدیم.
متد performance.now() برای اندازهگیریهای سریع و ساده، و متدهای
mark و measure برای تحلیلهای پیچیدهتر، ابزارهای حیاتی برای بهینهسازی و رفع
تنگناهای اجرایی در اپلیکیشنهای مدرن هستند. در درس بعدی، به سراغ یک موضوع بسیار مهم در معماری وب
مدرن، یعنی «کامپوننتهای وب» (Web Components) خواهیم رفت و یاد میگیریم که چگونه عناصر HTML
سفارشی، قابل استفاده مجدد و کپسولهشده بسازیم.