Вузькі місця в 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 | Багато reflow | Batch update |
| Пам'ять | Витоки | WeakMap, очищення |
| Цикли | O(n²) | Оптимізувати |
| Мережа | Повторні запити | Кешувати |
| Рендер | FPS < 60 | GPU-анімації |
| Бандл | 2 МБ JS | Tree-shaking |
| Алгоритми | Невірна структура | Підбір під задачу |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.