Отладчик и профилировщик
Отладчик отвечает «какие значения и вызовы привели к этому состоянию». Профилировщик — «куда уходит время или память». Лог полезен для наблюдения за последовательностью событий; остановка на breakpoint меняет время выполнения и может скрыть гонку. Сначала воспроизведите симптом на минимальном наборе данных.
Ошибка значения
Сохраните во временный debug.mjs:
function total(prices) {
return prices.reduce((sum, price) => sum + price, 0);
}
console.log(total([10, "20", 30]));
Запустите node debug.mjs: получится строка 102030. Запустите
node --inspect-brk=127.0.0.1:9237 debug.mjs с собственным свободным портом,
подключите Node debugger редактора либо Chrome через chrome://inspect.
Поставьте breakpoint внутри reducer, продолжите выполнение и смотрите
typeof sum, typeof price, Call Stack и Scope. Step over выполняет вызов,
step into входит в него; продолжение идёт до следующей точки остановки.
Inspector держите на loopback; после опыта завершите свой процесс.
Ошибка появилась до суммирования: вход содержит строку. Приведение as number[]
не исправляет runtime-данные. Выберите контракт: только числа или явно разрешённые
числовые строки. Проверьте вход на границе, затем добавьте проверку поведения.
Не преобразуйте любой нечисловой текст в 0: это скрывает ошибку данных.
CPU-профиль без дополнительной зависимости
Во временный profile.mjs:
function checksum() {
let value = 0;
for (let i = 0; i < 20_000_000; i++) value = (value + i) % 1_000_003;
return value;
}
console.log(checksum());
Из этого временного каталога:
node --cpu-prof --cpu-prof-name=lesson.cpuprofile profile.mjs
Получится число 1830 и файл профиля. Импортируйте его в Performance
DevTools. Найдите checksum в Call Tree, сравните self time с total time:
время собственного тела отличается от времени вместе с дочерними вызовами.
CPU-профиль основан на выборках; короткая функция может не попасть в выборку.
Результаты зависят от прогрева, компьютера и фоновой нагрузки. Повторяйте
сравнение на одинаковом входе и отдельно измеряйте общее время.
Исходник схемы
flowchart LR Symptom[Симптом] --> Reproduce[Воспроизводимый вход] Reproduce --> Hypothesis[Гипотеза] Hypothesis --> Measure[Breakpoint или профиль] Measure --> Change[Минимальная правка] Change --> Compare[Поведение и повторное измерение]
CPU-профиль не объяснит ожидание ответа CMS: процесс в это время может почти не использовать CPU. Сопоставьте сетевой waterfall, длительности запросов и трассировку. Не оптимизируйте reducer, если основная задержка — последовательные сетевые обращения.
Браузер и React
Performance показывает scripting, layout и paint; React Profiler — commits
и затраты компонентов. Изменение props может вызвать render, который ещё
не означает дорогое изменение DOM. Сначала найдите дорогой сценарий, затем
проверьте число вызовов, зависимости effects и расположение state. Добавление
memo или useMemo без измерения усложняет код и может ничего не ускорить.
Dev Strict Mode и production имеют разные условия; сравнение должно их учитывать.
Production-сборки проекта выполняются в CI, локально используйте dev и маленькие
изолированные примеры.
Для памяти сравнивайте heap snapshots после одинаковых действий и сборки мусора, ищите удерживающие ссылки: listeners, замыкания, коллекции. Рост RSS сам по себе не доказывает утечку JS-объектов. Heap snapshot может содержать значения данных; учебные профили собирайте с вымышленными входами и не коммитьте реальные снимки.
Приёмка: укажите исходный симптом, воспроизведение, наблюдение, причинную гипотезу и результат правки. Для ускорения покажите до/после с одинаковым входом, для ошибки — случай, который раньше давал неверный ответ. Нативные вычисления можно проверить отдельно; работа интерфейса debugger и браузерных профилей требует ручного опыта.
Источники: CLI Node.js 24, отладка Node, React Profiler.