Перейти к основному содержимому

Инструменты и библиотеки

Инструменты используются для измерения, диагностики и оптимизации. Использовать актуальные стабильные версии. Не добавлять инструмент без понимания того, что именно он измеряет или решает.


Измерения и профилирование

ИнструментНазначениеКогда использовать
web-vitalsRUM: сбор LCP / INP / CLS от реальных пользователейПродакшен, всегда
useReportWebVitals (Next.js)CWV + Next.js-специфичные метрики: hydration, route-change-to-renderNext.js проекты
PerformanceObserverСбор произвольных метрик у реальных пользователейRUM, продакшен
performance.mark/measureЗамер критичных операций вручнуюДиагностика конкретных мест
LighthouseLab: лабораторные замеры, аудит страницыДо / после оптимизаций
Chrome DevTools PerformanceПрофилирование main thread, поиск bottleneckДиагностика INP, Long Tasks
CrUX VisИсторические Field Data по доменуАнализ трендов

SHOULD

  • web-vitals или useReportWebVitals подключён в продакшене и отправляет метрики в аналитику.

Runtime-мониторинг (dev)

Инструменты для локальной диагностики проблемных рендеров — только в dev-окружении.

ИнструментЧто делает
React ScanВизуально подсвечивает компоненты с проблемными рендерами прямо в браузере
Why Did You Render (WDYR)Логирует причины лишних рендеров в консоль

Анализ бандла

SHOULD

Запускать при появлении подозрений на раздутый бандл или после добавления крупных зависимостей.

ИнструментПрименение
webpack-bundle-analyzerWebpack / Next.js проекты
source-map-explorerАнализ через source maps
vite-bundle-analyzerVite / Astro проекты

Виртуализация списков

SHOULD

Применяется когда список рендерит сотни и более элементов и вызывает заметные лаги при скролле.

БиблиотекаПрименение
@tanstack/react-virtualГибкая виртуализация, поддержка динамических высот
react-windowПростые случаи, фиксированные размеры
import { useVirtualizer } from '@tanstack/react-virtual';

function VirtualList({ items }: { items: string[] }) {
const parentRef = useRef<HTMLDivElement>(null);
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 40,
});

return (
<div ref={parentRef} style={{ height: '400px', overflow: 'auto' }}>
<div style={{ height: virtualizer.getTotalSize() }}>
{virtualizer.getVirtualItems().map((item) => (
<div
key={item.key}
style={{ transform: `translateY(${item.start}px)` }}
>
{items[item.index]}
</div>
))}
</div>
</div>
);
}

Lazy-load по видимости

SHOULD

Применяется для отложенной загрузки некритичных блоков — секций ниже fold, тяжёлых виджетов.

Библиотека: react-intersection-observer

import { useInView } from 'react-intersection-observer';

function LazySection() {
const { ref, inView } = useInView({ triggerOnce: true });

return <div ref={ref}>{inView ? <HeavyComponent /> : <Skeleton />}</div>;
}

Web Workers

Для тяжёлых вычислений вне main thread. Примеры из регламента:

  • Сортировка / фильтрация массивов > 5 000 объектов
  • Глубокое сравнение (diffing) сложных вложенных структур
  • Пересчёт координат для тысяч точек на графиках
  • Программная обработка Canvas-анимаций