Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Вузькі місця в JS-коді». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)JS-код має кілька типових **вузьких місць**: блокування основного потоку, надлишкові операції з DOM, витоки пам'яті, неефективні цикли, зайві мережеві запити, слабку оптимізацію відмальовування, важкий бандл, невдалі структури даних і відсутність профілювання. **Ключове:** кожна з цих проблем має конкретне рішення - від Web Workers і debounce/throttle до tree-shaking і профілювання через Chrome DevTools.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 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 | | Алгоритми | Невірна структура | Підбір під задачу |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.