JavaRush /Курсы /Модуль 3: React /Использование профилировщика в React DevTools для анализа...

Использование профилировщика в React DevTools для анализа

Модуль 3: React
10 уровень , 1 лекция
Открыта

Зачем использовать профилировщик?

Представьте, что вы ищете утечку воды в доме. Вы можете заменить все трубы, но, возможно, проблема только в одном месте. Точно так же с производительностью: нужно понимать, где именно проблема, перед тем как предпринимать действия. React DevTools — это "профессиональная камера для поиска утечек", которая поможет нам выявлять избыточные рендеры, долгие вычисления и другие проблемы.

Установка React DevTools

Если у вас ещё нет React DevTools, установите его:

  1. Откройте страницу React DevTools в вашем браузере.
  2. Установите расширение для Chrome или Firefox.
  3. Для локального проекта на create-react-app или других сборщиках убедитесь, что React работает в режиме разработки.

После установки вы увидите вкладку React в панелях разработчика браузера.

Введение в профилирование React-приложения

React DevTools предоставляет вкладку Profiler, которая позволяет записывать производительность реактивных компонентов внутри приложения. Это похоже на запись ваших действий на камеру для последующего анализа.

Включение профилирования

  1. Откройте приложение в режиме отладки.
  2. Откройте инструменты разработчика браузера.
  3. Перейдите во вкладку React, затем — во вкладку Profiler.
  4. Нажмите "Start Profiling", чтобы начать запись производительности.

Анализ профиля

После записи профиля вы увидите графический интерфейс с рендерингом компонентов, их вызовами и временем выполнения. Давайте разберём ключевые элементы.

Основные элементы профилировщика

  1. Флэймграф (Flamegraph):

    • Похоже на перевёрнутую пирамиду.
    • Каждый слой представляет компонент.
    • Чем шире компонент, тем больше времени он занимает.
  2. Индивидуальный рендеринг компонентов:

    • Нажмите на конкретный компонент.
    • В правой панели вы увидите, сколько времени заняло его рендеринг, и частоту изменений.
  3. Причины рендеринга:

    • Указывает, что вызвало повторный рендер.
    • Например: изменение пропсов или стейта.

Практический пример: где проблема?

Представим, что у нас есть простое приложение по управлению задачами. Вот его структура:

import React, { useState } from "react";

const TaskList: React.FC = () => {
  const [tasks, setTasks] = useState<string[]>(["Сделать React-приложение", "Помыть кота"]);
  const [filter, setFilter] = useState("");

  const filteredTasks = tasks.filter((task) => task.includes(filter));

  return (
    <div>
      <input value={filter} onChange={(e) => setFilter(e.target.value)} placeholder="Поиск задач" />
      <ul>
        {filteredTasks.map((task, index) => (
          <TaskItem key={index} task={task} />
        ))}
      </ul>
    </div>
  );
};

const TaskItem: React.FC<{ task: string }> = ({ task }) => {
  console.log(`Рендерится задача: ${task}`);
  return <li>{task}</li>;
};

export default TaskList;

Где проблема?

  1. Запустим профилировщик. Вводим текст в поле фильтра.
  2. В Profiler мы видим, что каждый TaskItem снова рендерится при каждом вводе в поле! Даже если задача не меняется.

Как исправить?

Шаг 1: Мемоизация компонентов

Используем React.memo, чтобы предотвратить лишний рендер:

const TaskItem: React.FC<{ task: string }> = React.memo(({ task }) => {
  console.log(`Рендерится задача: ${task}`);
  return <li>{task}</li>;
});

Теперь в профилировщике видно, что только изменённые компоненты TaskItem рендерятся при вводе!

Шаг 2: Оптимизация фильтрации

Ещё один совет: если список задач стабилен, используйте useMemo для кэширования результата фильтрации.

import React, { useState, useMemo } from "react";

const TaskList: React.FC = () => {
  const [tasks] = useState<string[]>(["Сделать React-приложение", "Помыть кота"]);
  const [filter, setFilter] = useState("");

  const filteredTasks = useMemo(() => {
    return tasks.filter((task) => task.includes(filter));
  }, [tasks, filter]);

  return (
    <div>
      <input value={filter} onChange={(e) => setFilter(e.target.value)} placeholder="Поиск задач" />
      <ul>
        {filteredTasks.map((task, index) => (
          <TaskItem key={index} task={task} />
        ))}
      </ul>
    </div>
  );
};

Теперь профилировщик покажет, что фильтрация больше не выполняется на каждом рендере, а задача рендерится только при изменении filter.

Частые ошибки при профилировании

  1. Запуск профилирования на продакшене: профилируйте только в режиме разработки! На продакшене React убирает некоторые проверки для скорости, что может повлиять на результаты.

  2. Не забывайте о зависимостях: убедитесь, что все зависимости правильно указаны в useMemo или useCallback.

  3. Слишком ранняя оптимизация: профилирование нужно для выявления реальных проблем, а не для "страха рендеров". Иногда лишние рендеры оправданы, если они не критичны для производительности.

1
Задача
Модуль 3: React, 10 уровень, 1 лекция
Недоступна
Анализ производительности
Анализ производительности
1
Задача
Модуль 3: React, 10 уровень, 1 лекция
Недоступна
Оптимизация приложения
Оптимизация приложения
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ