Что убивает перформанс JS
Сводный чек-лист по разборам AsForJS: типичные «убийцы» производительности, которые встречаются в проде чаще всего.
TOP-killers
1. Аллокация в горячем цикле
// УБИВАЕТ: миллион промежуточных объектов
for (let i = 0; i < N; i++) {
const tmp = { x: arr[i], y: i }; // мусор для GC
process(tmp);
}
// Лучше: переиспользуй
const tmp = { x: 0, y: 0 };
for (let i = 0; i < N; i++) {
tmp.x = arr[i];
tmp.y = i;
process(tmp);
}
2. Универсальная функция на разных формах
→ Monomorphic Polymorphic Megamorphic
3. Forced reflow / layout thrashing
// УБИВАЕТ: чтение layout-свойства в цикле = synchronous reflow
elements.forEach(el => {
const h = el.offsetHeight; // reflow
el.style.width = h + 'px'; // invalidate
});
// Лучше: read all → write all
const heights = elements.map(el => el.offsetHeight);
elements.forEach((el, i) => { el.style.width = heights[i] + 'px'; });
4. Слушатели событий без removeEventListener
Любая ссылка на DOM-узел из callback мешает GC. На SPA это утечка памяти за минуты.
5. Большие JSON.stringify синхронно
Блокирует main thread. На больших данных — Worker, потоковая сериализация или incremental.
6. Регэкспы без g/y в цикле
/abc/.test(...) создаёт matchstate каждый раз. Кэшируй regex как const.
7. Promise chain с лишними await
// УБИВАЕТ: 3 микротаски
const a = await fetch(...);
const b = await fetch(...);
const c = await fetch(...);
// Лучше: параллельно
const [a, b, c] = await Promise.all([fetch(...), fetch(...), fetch(...)]);
8. Скрытый O(n²) через arr.includes в цикле
Источники
- Обзор: 2 вещи которые убивают перформанс в JavaScript · AsForJS · 2023-06-01
- Введение в производительность JavaScript кода · AsForJS · 2023-06-07
- Про оптимизацию JavaScript данных в браузере (dlgs6) · AsForJS · 2024-03-26
- Оптимизация Frontend приложений (23 совета) · AsForJS · 2024-08-04