Performance.now: примеры (JAVASCRIPT)
performance.now: NumberОписание функции performance.now()
Метод performance.now() возвращает значение DOMHighResTimeStamp, измеряемое в миллисекундах. Это значение представляет собой время, прошедшее с момента начала навигации страницы или с момента запуска текущего рабочего процесса в Node.js.
Основное применение — точные измерения производительности участков кода. Отличительная черта — монотонное увеличение значения, что защищает от корректировок системного времени. В браузерах значение имеет микросекундную точность, но округляется до 5 микросекунд для защиты от fingerprinting.
Функция не принимает аргументов. Возвращаемое значение — число с плавающей запятой, выражающее время в миллисекундах.
Короткие примеры использования
Базовый пример замера времени выполнения операции.
const start = performance.now();
for (let i = 0; i < 1000000; i++) { Math.sqrt(i); }
const end = performance.now();
console.log(`Время выполнения: ${end - start} мс`);Время выполнения: 12.345678901234567 мс
Измерение времени асинхронной операции.
async function fetchData() {
const start = performance.now();
await fetch('https://jsonplaceholder.typicode.com/posts/1');
const end = performance.now();
console.log(`Запрос занял: ${(end - start).toFixed(2)} мс`);
}
fetchData();Запрос занял: 156.78 мс
Похожие функции в JavaScript
Date.now() возвращает количество миллисекунд, прошедших с 1 января 1970 года. Менее точна, не монотонна, подвержена корректировкам системного времени.
console.time() / console.timeEnd() предоставляет простой способ замера с помощью меток. Удобен для отладки, но менее гибок по сравнению с performance.now().
performance.mark() и performance.measure() являются частью Performance Timeline API. Позволяют создавать именованные метки и измерять интервалы между ними, интегрируясь с инструментами разработчика.
Для большинства задач точного замера производительности performance.now() является предпочтительным выбором.
Альтернативы в других языках
Python (time.perf_counter): Возвращает время с максимальной доступной точностью для измерения коротких интервалов.
import time
start = time.perf_counter()
# Код
end = time.perf_counter()
print(f'Время: {end - start} секунд')Время: 0.123456789 секунд
PHP (microtime): Возвращает текущую метку времени в микросекундах. Требует парсинга строки или использования параметра true для получения float.
$start = microtime(true);
// Код
$end = microtime(true);
echo 'Время: ' . ($end - $start) . ' секунд';Время: 0.000123 секунд
C (clock()): Возвращает процессорное время, затраченное на выполнение программы. В отличие от performance.now(), измеряет именно использование CPU.
#include
#include
int main() {
clock_t start = clock();
// Код
clock_t end = clock();
double time_spent = (double)(end - start) / CLOCKS_PER_SEC;
printf("Время: %f секунд\n", time_spent);
return 0;
} Время: 0.123000 секунд
Типичные ошибки
Неправильное вычисление разницы: использование только одного вызова функции.
// ОШИБКА: Замер без вычисления разницы
const t = performance.now();
someOperation();
console.log(`Время: ${t} мс`); // Выводит начальное время, а не интервалВремя: 12345.678 мс
Попытка использовать возвращаемое значение как абсолютную временную метку, например, для сравнения с Date.now().
// ОШИБКА: Смешивание разных систем времени
const perfTime = performance.now();
const dateTime = Date.now();
// Не имеет смысла, так как точки отсчета разные
console.log(perfTime - dateTime);-1691234567890.123 (пример отрицательного значения)
Использование для измерения интервалов больше допустимой точности, что может привести к переполнению или потере точности, хотя это маловероятно для практических задач.
Изменения в последних версиях
В спецификации High Resolution Time Level 2 изменился источник времени для performance.now() в браузерах. Теперь используется монотонный时钟, не привязанный к системному времени, что повышает надежность.
В Node.js метод performance.now() появился в версии 8.5.0 как экспериментальный, а в версии 16.0.0 стал стабильным. В Node.js 19.0.0 была увеличена точность до наносекунд (1e-9) в некоторых системах.
Для кросс-браузерной совместимости стоит учитывать, что в очень старых браузерах (IE9) метод мог отсутствовать или иметь префикс (msPerformance.now()).
Расширенные примеры
Измерение продолжительности нескольких операций с агрегацией.
const measurements = [];
for (let i = 0; i < 10; i++) {
const start = performance.now();
// Имитация работы
for (let j = 0; j < 10000; j++) {}
const end = performance.now();
measurements.push(end - start);
}
const avg = measurements.reduce((a, b) => a + b) / measurements.length;
console.log(`Среднее время: ${avg.toFixed(3)} мс`);
console.log(`Все замеры:`, measurements);Среднее время: 0.045 мс Все замеры: [0.04, 0.05, 0.04, ...]
Использование в Web Worker для замера производительности в отдельном потоке.
// main.js
const worker = new Worker('worker.js');
worker.postMessage('start');
// worker.js
self.onmessage = function(e) {
const start = performance.now();
// Интенсивные вычисления
let sum = 0;
for (let i = 0; i < 1e7; i++) sum += i;
const end = performance.now();
self.postMessage(`Вычисления заняли ${end - start} мс`);
};Вычисления заняли 120.5 мс
Интеграция с PerformanceObserver для наблюдения за метками.
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(`${entry.name}: ${entry.duration}`);
}
});
observer.observe({ entryTypes: ['measure'] });
performance.mark('start-mark');
// ... код
performance.mark('end-mark');
performance.measure('my-measure', 'start-mark', 'end-mark');my-measure: 15.678
Сравнение производительности разных алгоритмов.
function algorithmA(n) { /* ... */ }
function algorithmB(n) { /* ... */ }
function benchmark(func, input) {
const start = performance.now();
func(input);
const end = performance.now();
return end - start;
}
const timeA = benchmark(algorithmA, 1000);
const timeB = benchmark(algorithmB, 1000);
console.log(`Алгоритм A: ${timeA} мс, Алгоритм B: ${timeB} мс`);Алгоритм A: 5.123 мс, Алгоритм B: 3.456 мс