Skip to main content

Як виміряти продуктивність JS-коду?

Швидкі виміри (інструментування в коді)

Браузер

javascript
// Точний таймер (у мс, з частками) const t0 = performance.now(); // ... код ... const t1 = performance.now(); console.log(`Час: ${(t1 - t0).toFixed(2)} ms`);
javascript
// User Timing API: мітки і вимірювання performance.mark('A'); // ... код ... performance.mark('B'); performance.measure('my-op', 'A', 'B'); console.table(performance.getEntriesByName('my-op'));
javascript
// Швидко і просто console.time('op'); // ... код ... console.timeEnd('op');

Node.js

javascript
// perf_hooks - монотонні таймери const { performance, PerformanceObserver } = require('node:perf_hooks'); performance.mark('A'); // ... код ... performance.mark('B'); performance.measure('op', 'A', 'B'); new PerformanceObserver(list => console.table(list.getEntries())) .observe({ entryTypes: ['measure'] });

Профілювання (щоб зрозуміти, "де" гальмує)

Браузер DevTools

  • Performance (або Performance Insights): запис → отримаєш flame chart (гарячі функції), FPS, layout/recalc style, long tasks (≥50 ms).
  • Memory: Heap snapshot / Allocation instrumentation - шукаємо витоки і "сміття".
  • Coverage: скільки JS/CSS реально виконується (впливає на TBT).

Node.js

  • node --inspect і Chrome DevTools → CPU profile, heap.
  • node --prof + prof-process або clinic.js / 0x для зручних графів полум'я.

Мікробенчмарки (порівняти реалізації)

  • Benchmark.js / tinybench - роблять прогрів JIT, багато ітерацій, статистику.
javascript
import Benchmark from 'benchmark'; const suite = new Benchmark.Suite(); function a(arr){ /* варіант A */ } function b(arr){ /* варіант B */ } suite .add('A', () => a(data)) .add('B', () => b(data)) .on('cycle', e => console.log(String(e.target))) .on('complete', function () { console.log('Faster:', this.filter('fastest').map('name')); }) .run({ async: true });

Важливо: прогрівай тест (discard first run), фіксуй вхідні дані, запускай кілька прогонів, вимикай зайві вкладки/розширення.

Вимірювання "переживаності" UI

  • Long Tasks API: ловимо блокування головного потоку.
javascript
new PerformanceObserver((list) => { for (const e of list.getEntries()) { console.log('Long task', e.duration.toFixed(1), 'ms'); } }).observe({ entryTypes: ['longtask'] });
  • rAF/FPS: простий індикатор плавності.
javascript
let last = performance.now(), frames = 0; function tick(ts){ frames++; if (ts - last >= 1000) { console.log('FPS:', frames); frames = 0; last = ts; } requestAnimationFrame(tick); } requestAnimationFrame(tick);

Мережеві і рендер-метрики (сторінкові)

  • Navigation/Resource Timing (performance.getEntriesByType('navigation'|'resource')) - TTFB, завантаження ресурсів.
  • Core Web Vitals (LCP, CLS, INP/TBT) - став web-vitals у реальному трафіку.
  • Lighthouse (разово) - регресії, але не замінює польові метрики.

Методика: як міряти коректно

  1. Сформулюй мету (CPU-частина? GC? Layout? Мережа?).
  2. Ізолюй контекст: вимкни мережу/DOM, якщо міряєш чистий алгоритм.
  3. Прогрій JIT: зроби кілька "холостих" запусків.
  4. Повторення і статистика: медіана/квантилі важливіші за середнє.
  5. Контролюй шум: фіксуй дані, розмір входу, обмеж фонові процеси.
  6. Дивись на полум'я (flame chart), а не тільки цифри - оптимізуй "гарячі" вузькі місця.
  7. Перевіряй регресії в CI (наприклад, невеликий бенч + пороги).

Що міряти в типових сценаріях

  • Алгоритм/колекції → microbench (Benchmark.js) + performance.now.
  • Інтерактивність UI → DevTools Performance + Long Tasks + FPS.
  • Рендер/стилі → вкладки Rendering/Layout/Styles у профайлері, уникай layout-thrashing.
  • Пам'ять/витоки → Heap snapshots, Allocation timeline.
  • Node API → perf_hooks, CPU profile, перевірка sync-методів (замінити на async/worker_threads).

Антипатерни

  • Один прогін "на око" - шум і JIT спотворять картину.
  • Мікробенчі DOM-операцій: результати залежать від реального дерева/стилів. Профілюй у DevTools.
  • Порівнювати без однакових вхідних даних.
  • Оптимізувати без flamechart - легко "лікувати не те місце".

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.