Skip to main content

Вузькі місця в JS-коді

1. Блокування основного потоку (Main Thread Blocking)

JS - однопотоковий. Будь-яка важка операція блокує UI, рендеринг і обробку подій.

Приклади:

  • великі цикли (for, while, forEach) без setTimeout/requestIdleCallback;
  • парсинг або обробка великих JSON (JSON.parse(hugeData));
  • обчислювально важкі алгоритми (сортування, рекурсії, шифрування);
  • синхронні запити (XMLHttpRequest без async);
  • великі DOM-зміни в одному фреймі.

Як виправити:

  • розбивай роботу на чанки (setTimeout, requestAnimationFrame);
  • використовуй Web Workers для фонових обчислень;
  • застосовуй debounce / throttle для подій.

2. Надлишкові рендери і маніпуляції DOM

DOM-операції - найдорожчі з погляду продуктивності.

Проблеми:

  • надто часті вставки/видалення елементів;
  • перерахунок стилів і layout при кожній зміні;
  • звернення до offsetHeight, getComputedStyle, scrollTop → викликає reflow;
  • цикли, в яких відбувається зміна DOM.

Як виправити:

  • використовувати DocumentFragment, virtual DOM, Batch updates;
  • кешувати посилання на елементи;
  • мінімізувати reflow - змінювати клас одразу для групи елементів;
  • у React: мемоізація, PureComponent, React.memo, useMemo, useCallback.

3. Надлишкове споживання пам'яті (Memory leaks)

Витоки пам'яті призводять до того, що вкладка "важчає", UI зависає.

Причини:

  • неочищені таймери (setInterval, setTimeout);
  • "висячі" слухачі подій (не видаляються при видаленні елемента);
  • замикання, що утримують посилання на великі об'єкти;
  • глобальні змінні (ніколи не очищаються);
  • кеші, які не очищаються.

Рішення:

  • чистити таймери (clearInterval, clearTimeout);
  • знімати обробники (removeEventListener);
  • використовувати WeakMap / WeakSet;
  • аналіз через Chrome DevTools → Memory.

4. Неефективні цикли і колекції

Особливо на великих масивах.

Типові помилки:

  • вкладені цикли O(n²) без потреби;
  • використання .map() / .filter() / .reduce() на великих масивах без оптимізації;
  • створення нових масивів/об'єктів на кожній ітерації;
  • часті виклики Array.splice() / Array.shift() (дорогі операції).

Що робити:

  • використовувати доречніші структури: Set, Map, WeakMap;
  • використовувати ітератори, генератори, for...of замість forEach при великих обсягах;
  • профілювати ділянки з performance.now().

5. Надлишкові мережеві запити

Навіть швидкий JS-код не врятує, якщо мережа "забита".

Проблеми:

  • повторні запити без кешу;
  • дубльовані API-виклики при кожному рендері;
  • завантаження величезних бандлів JS/CSS;
  • немає gzip / brotli стиснення;
  • немає lazy loading.

Як виправити:

  • кешування (HTTP-кеш, IndexedDB, SW, мемоізація);
  • об'єднання запитів (batching);
  • React Query, SWR, Cache-Control;
  • код-сплітинг і динамічний імпорт (import()).

6. Слабка оптимізація відмальовування (Rendering bottlenecks)

UI "смикається", анімації тормозять, FPS падає.

Причини:

  • надто часта зміна style/transform;
  • використання важких тіней, фільтрів, border-radius;
  • невикористання GPU (CSS-анімації без transform: translateZ(0));
  • перерахунок layout у кожному кадрі анімації.

Рішення:

  • виносити анімації на GPU;
  • об'єднувати зміни DOM за один кадр;
  • використовувати will-change, transform, opacity;
  • requestAnimationFrame замість таймерів для анімацій.

7. Важкий бандл (Bundle Size)

Чим більше JS - тим довше завантаження і парсинг.

Причини:

  • підключення зайвих бібліотек;
  • дублювання залежностей;
  • невикористання tree-shaking;
  • inline JSON, великі іконки, зображення в коді.

Рішення:

  • аналіз бандла (webpack-bundle-analyzer, next build --analyze);
  • tree-shaking, code splitting, dynamic import();
  • використовувати CDN, HTTP/2, ESM-бандли;
  • мінифікація (Terser, SWC).

8. Неоптимальні структури даних і алгоритми

Приклад: сортування масиву на 100 000 елементів через sort() без компаратора або пошук через filter() замість Set.

Що робити:

  • обирати структуру під задачу: Set для унікальності, Map для швидкого lookup;
  • уникати лінійного пошуку, коли можна використати хеш-пошук;
  • використовувати бінарний пошук, кешування обчислень.

9. Відсутність профілювання і метрик

Найчастіша помилка - "оптимізація навмання".

Рішення:

  • Chrome DevTools (Performance, Memory, Coverage);
  • console.time(), performance.mark() / measure();
  • Lighthouse / Web Vitals;
  • Sentry Performance, New Relic, Datadog.

Коротке резюме

КатегоріяПриклад проблемиЯк виправити
Блокування потокуДовгий циклРозбити, Worker
DOMБагато reflowBatch update
Пам'ятьВитокиWeakMap, очищення
ЦиклиO(n²)Оптимізувати
МережаПовторні запитиКешувати
РендерFPS < 60GPU-анімації
Бандл2 МБ JSTree-shaking
АлгоритмиНевірна структураПідбір під задачу

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

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

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