$ case open sfera-memory

Как мы снизили память real-time портала примерно вдвое

Инженерный разбор долгоживущего React-интерфейса: от отдельного инструмента на Puppeteer и fork’е fuite до автоматических heap snapshots и проверки под той же нагрузкой.

≈10/с
событий в real-time потоке
≤5000
событий в истории
400–500+
МБ до оптимизации
150–250
МБ после оптимизации

01 / Контекст

Проблема проявлялась не в одном рендере, а со временем

Портал мониторинга СФЕРА работал с непрерывным потоком событий и WebSocket-графиками. Для такой системы важна не только скорость первого экрана: вкладка должна оставаться стабильной после долгой работы и повторяющихся пользовательских сценариев.

Моя роль

Senior frontend-разработчик: структура приложения, ключевые UI-сценарии, интеграции и производительность.

Системная нагрузка

Около 10 событий в секунду, история до 5000 событий и обновляемые по WebSocket графики.

Инженерная задача

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

02 / Расследование

От воспроизводимого сценария к проверке исправлений

Четыре этапа связывают одинаковый сценарий нагрузки, автоматизированные heap snapshots, поиск удерживаемых объектов и повторный прогон после исправлений.

memory-investigation.logВоспроизведение расследования
01 / 04
Память вкладкиизмеренные диапазоны
До400–500+ MB
После150–250 MB

Сравнение диапазонов памяти в одинаковом сценарии нагрузки до и после исправлений.

Сценарий

Зафиксировать воспроизводимый путь

Сначала — стабильный сценарий долгой сессии, а не случайный снимок вкладки.

  • Real-time поток около 10 событий в секунду
  • История до 5000 событий и WebSocket-графики
  • Одинаковая последовательность действий между замерами

03 / Решения

Три решения, которые сделали результат проверяемым

01

Один сценарий для всех прогонов

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

Дольше одного ручного замера, зато результат воспроизводим.
02

Fork fuite вместо обхода его ограничений

В fork’е исправили освобождение ресурсов через dispose, чтобы сам диагностический прогон не искажал результат.

Нужно поддерживать fork, зато измерениям можно доверять.
03

Проверка долгой сессии

Финальный прогон повторял поток событий и историю, близкие к реальному режиму работы портала.

Медленнее микротеста, зато проверяется продуктовый сценарий.
Инструменты расследования
ReactTypeScriptMobXWebSocketChrome DevToolsReact ProfilerfuitePuppeteer

04 / Результат

Память вкладки снизилась с 400–500+ до 150–250 МБ

Главный результат — не только меньшая цифра, а повторяемый способ находить и проверять подобные регрессии в real-time интерфейсе.

До400–500+ MB
После150–250 MB

Производительность

Работа с долгоживущим состоянием и профилированием, а не только Lighthouse.

Инструментарий

Отдельный Puppeteer-инструмент, fork fuite с dispose и автоматические heap snapshots.

Инженерное мышление

Гипотеза → воспроизведение → сравнение → проверка тем же сценарием.

$ next

Продолжить с архитектурным кейсом

Дальше — банковская onboarding-платформа с общей React/TypeScript-библиотекой для пяти приложений.