React
Профайлинг и React Performance Tracks
Список тормозит при наборе текста в поле поиска. Первое объяснение, что приходит в голову - надо всё обернуть в useMemo и memo. Разработчик расставляет мемоизацию наугад по всему дереву, тратит день, и список тормозит ровно так же, потому что узкое место было в другом компоненте. Без измерений оптимизация это гадание. React DevTools Profiler и новые React Performance Tracks в браузере показывают, какие компоненты и почему перерисовываются и сколько это стоит. Сначала измерить, потом чинить - и чинить именно то, что действительно медленно.
- Большие списки и таблицы, где лишние ре-рендеры строк превращают набор текста в подтормаживание
- Дашборды с частыми обновлениями данных, где важно не перерисовывать половину экрана на каждое изменение
- Команды, ставящие бюджеты производительности в CI, чтобы регрессия скорости ловилась как ошибка
- Отладка ре-рендеров через Profiler перед тем, как добавлять мемоизацию или включать React Compiler
- React Performance Tracks (19.2) в стандартной панели производительности Chrome для связи работы React с кадрами браузера
Предварительные знания
- Ре-рендеры: когда и почему компонент перерисовывается
- Мемоизация: memo, useMemo, useCallback и их назначение
- Базовое умение открыть DevTools и вкладку производительности браузера
От догадок к измеримому профайлингу
Долго оптимизация React была интуитивной: разработчики расставляли shouldComponentUpdate и мемоизацию по ощущениям. В 2018 команда React выпустила Profiler в DevTools - он записывал каждый коммит и показывал, что и сколько рендерилось. Это дало измеримость вместо догадок. Следующий шаг сделала версия 19.2 (октябрь 2025): React Performance Tracks встроились прямо в стандартную панель производительности браузера, показывая работу планировщика и компонентов на той же временной шкале, что и кадры, layout и paint. Теперь работу React видно в общем контексте браузера, а не только в отдельном инструменте.
React DevTools Profiler: измерение коммитов
Profiler в React DevTools записывает сессию взаимодействия и разбивает её на коммиты - моменты, когда React применил изменения к DOM. Для каждого коммита видно, какие компоненты рендерились, сколько времени заняла их отрисовка и почему рендер случился. Это превращает абстрактное это тормозит в конкретное вот этот компонент рендерился двести раз без надобности.
Ключевой инструмент это flame chart и опция подсветки причины рендера. Profiler показывает, что вызвало перерисовку: изменились пропсы, состояние, контекст или родитель. Часто обнаруживается, что компонент рендерится из-за нового объекта или функции, создаваемых родителем на каждом рендере, хотя данные по сути те же.
Включённая в Profiler настройка подсветки обновлений (highlight updates) рисует рамку вокруг перерисовывающихся компонентов прямо на странице. Если рамка мигает по всему экрану при изменении одного поля, это наглядный сигнал лишних ре-рендеров.
Зачем профилировать приложение перед добавлением мемоизации?
React Performance Tracks в панели браузера
React 19.2 добавил Performance Tracks - дорожки React прямо в стандартной панели производительности браузера, рядом с дорожками сети, JavaScript, layout и paint. Раньше работа React и работа браузера измерялись в разных инструментах, и связать их было трудно. Теперь видно, как рендер компонента ложится на ту же временную шкалу, что и кадры и пользовательский ввод.
| Инструмент | Что показывает | Сильная сторона |
|---|---|---|
| DevTools Profiler | Коммиты, дерево компонентов, причины рендера | Детально по компонентам React |
| Performance Tracks (19.2) | Работа React на общей шкале браузера | Связь рендера с кадрами, paint, вводом |
| Performance-панель браузера | Сеть, JS, layout, paint, кадры | Полная картина рантайма страницы |
Дорожки разделяют типы работы React: какие обновления планировщик считает срочными (ввод, клики), а какие может отложить как переходные (transition). Это позволяет увидеть, не блокирует ли тяжёлый рендер реакцию интерфейса на ввод и укладывается ли кадр в бюджет около 16 миллисекунд для 60 кадров в секунду. Профайлер DevTools отвечает на вопрос какой компонент, а Performance Tracks на вопрос как это влияет на плавность.
Практический сценарий: запись показывает длинную задачу JavaScript, перекрывающую несколько кадров, и на дорожке React видно, что её занимает рендер большого списка. Связав это с дорожкой ввода, можно подтвердить, что именно этот рендер задерживает отклик на нажатие клавиши. Дальше решение - виртуализация списка или перенос обновления в transition.
Performance Tracks доступны в дев-сборке React. Для честного замера производительности измеряют на продакшен-сборке: дев-сборка делает дополнительные проверки и предупреждения, поэтому в ней рендер заметно медленнее реального.
Что нового дают React Performance Tracks из 19.2 по сравнению с DevTools Profiler?
Лишние ре-рендеры и бюджеты производительности
Лишний (wasted) ре-рендер это перерисовка компонента, чей видимый результат не изменился. React вызвал функцию компонента, заново посчитал дерево, сравнил его - и не нашёл, что менять в DOM. Сама отрисовка прошла впустую, но процессорное время потрачено. На большом дереве сумма таких холостых рендеров и есть причина подтормаживания при вводе.
Когда профайлер подтвердил, что Child рендерится впустую из-за новых ссылок, стабилизация пропсов через useMemo и useCallback вместе с memo на Child устраняет холостые рендеры. React Compiler делает это автоматически, но измерять эффект всё равно нужно профайлером. Важно чинить подтверждённую причину, а не мемоизировать всё подряд - лишняя мемоизация сама стоит сравнений и памяти.
Бюджет производительности это заданный заранее порог, за который метрика не должна выходить: например, время взаимодействия, объём JavaScript-бандла или длительность ключевого рендера. Бюджет переводит производительность из субъективного ощущения в проверяемое число. В CI его нарушение ловится автоматически - регрессия скорости видна как красный билд, а не как жалоба пользователя через месяц.
| Метрика бюджета | Пример порога | Где проверяют |
|---|---|---|
| Размер JS-бандла | Не больше заданного KB на маршрут | Сборка и CI |
| Interaction to Next Paint | Отклик в пределах целевых миллисекунд | Полевые метрики, лаб-замеры |
| Время ключевого рендера | Кадр укладывается около 16 мс | Performance Tracks, профайлер |
Бюджет полезен, только если измеряется на продакшен-сборке и на репрезентативном устройстве. Замер на мощной машине разработчика в дев-режиме даёт обманчиво хорошие числа и пропускает регрессии, которые почувствуют пользователи на слабых телефонах.
Что такое лишний (wasted) ре-рендер?
Связь с другими темами
Этот урок про измерение производительности. Рядом стоят соседние темы:
- Мемоизация — Профайлер показывает, где мемоизация реально устраняет лишние ре-рендеры, а где она лишняя
- React Compiler — Компилятор автоматизирует мемоизацию, но измерять результат по-прежнему нужно профайлером
Итог
- Оптимизация без измерений это гадание: сначала профайлер находит узкое место, потом чинится именно оно
- React DevTools Profiler записывает коммиты и показывает, какие компоненты перерисовались, почему и сколько это заняло
- React Performance Tracks (19.2) выводят работу планировщика и компонентов прямо в панель производительности браузера
- Лишний ре-рендер это перерисовка компонента, чей видимый результат не изменился: профайлер подсвечивает такие случаи
- Бюджет производительности это заданный порог (время рендера, объём бандла), нарушение которого ловится как регрессия
- Мемоизацию и React Compiler применяют по данным профайлера, а не наугад по всему дереву
Связанные уроки
- rc-19-memoization — Профайлинг показывает, где мемоизация действительно нужна, а где она избыточна
- rc-20-react-compiler — React Compiler автоматизирует часть оптимизаций, но профайлер по-прежнему нужен для измерений