Библиотека scroll.ts (scrollThrough) с тестами на фикстурах, сценарий scroll.spec.ts: листы форм, отчёты проектов, своды 1/2, projects/summaries, admin-контроль, смена фильтра свода. Параметры PERF_TARGETS/CPU_RATES/REPEATS/ROLES/AXES. Refs #202 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Профилирование: perf/
Стенд
Требования: Docker, python3.12, Node 24, npm.
perf/stand.sh all # up, migrate, bootstrap, web-build, api, web, smoke
perf/stand.sh down # остановить бэк, фронт и Postgres
Подкоманды: up | migrate | bootstrap | api | web-build | web | smoke | reset | down | all.
reset — чистая БД: останавливает бэк, сносит volume Postgres, поднимает заново (up, migrate, bootstrap, api); фронт не трогает.
- Postgres 16 (
pg_stat_statements) наlocalhost:55432,perf/perf/perf. - Бэк (
DEBUG=true) наhttp://localhost:8000, логи и PID вperf/.run/. - Фронт (prod-сборка,
rsbuild preview) наhttp://localhost:8080;/api(включая WebSocket) проксируется на бэк. - Профилирующая сборка (
PERF_PROFILING=1,react-dom/profiling) лежит вperf/.build/profiling, обычная вperf/.build/prod. Для запуска preview с профилирующей сборкой:PERF_PROFILING=1 perf/stand.sh web(после остановки обычногоweb). - Админ:
admin/admin. - Переменные:
PERF_API,PERF_WEB,PERF_DB_DSN. - Зависимости Python ставятся в
perf/.venv(api/requirements-dev.txt+perf/requirements.txt). - npm берёт пакеты с
https://registry.npmjs.org(npm_config_registry),web/.npmrcне нужен.
Данные
perf/stand.sh reset # пустая БД (генератор на непустой БД откажется работать)
cd perf && .venv/bin/python -m perfkit.gen.run --scale 1 # ~20-40 мин, пишет results/manifest-s1.json
cd perf && .venv/bin/python -m perfkit.gen.verify --scale 1 # должен напечатать VERIFY OK
Генератор работает через HTTP-API под admin (WebSocket — только для программ и проектов FORM_4,
у них нет HTTP-ручки). Пользователи: perf_rf, perf_rf_coauthor (одна РФ, роль 3) и perf_dfip
(роль 2, все оргединицы), пароль perf; в манифесте они под ключами rf, rf_coauthor, dfip.
Числа плана и их обоснование — в perf/perfkit/gen/plan.py.
Фронт: замеры
Каркас: perf/e2e (Playwright + CDP). Версии: @playwright/test 1.64.1, Chromium 156.0.8078.4 (headless shell, revision 1248).
cd perf/e2e && npm install && npx playwright install chromium # npm_config_registry=https://registry.npmjs.org
npx playwright test tests/harness.spec.ts # самопроверка каркаса
PERF_RUN_ID— имя каталога прогонаperf/results/<run_id>/(по умолчаниюYYYYMMDD-HHMM).PERF_SCALE— масштаб манифестаperf/results/manifest-s<scale>.json(по умолчанию 1).PERF_API,PERF_WEB— адреса стенда (http://localhost:8000,http://localhost:8080).- Агрегация:
cd perf && .venv/bin/python -m perfkit.aggregate results/<run_id>. - Библиотеки
perf/e2e/lib/:auth.loginAs,cdp.*(throttle, trace, gc, heap),probe(long tasks > 50 мс, кадры rAF; тяжёлый кадр — интервал > 50 мс),results.append,manifest.loadManifest.
Сценарии скролла
perf/e2e/scenarios/scroll.spec.ts, библиотека lib/scroll.ts (scrollThrough: колесо мыши шагами по 200 px вниз/вправо до конца и обратно, complete = scrollTop + clientHeight >= scrollHeight - 2). Самопроверка: npx playwright test tests/scroll-lib.spec.ts.
cd perf/e2e
PERF_RUN_ID=s1 PERF_SCALE=1 npx playwright test scenarios/scroll.spec.ts # вся матрица масштаба (долго!)
PERF_RUN_ID=t PERF_TARGETS='FORM_2/AHR/*' PERF_CPU_RATES=1 PERF_REPEATS=1 npx playwright test scenarios/scroll.spec.ts
cd .. && .venv/bin/python -m perfkit.aggregate results/s1
- Матрица: роль
rfx листы сowner=rfи отчёты проектов x оси y,x x CPU 1,4,6 x 3 повтора;adminx все листы x ось y x CPU x 1 повтор (только масштаб 1);adminиdfipx своды (svod1_MAIN/FORM_1..4, svod2_GO/RF, projects_summaries) x ось y x CPU x 3 повтора + одна смена фильтра на CPU 6 (target.../filter). - target:
FORM_x/<sheet>/<direction|null>,project/<report_type>/<project_id>,svod/<name>; к записи добавляется суффикс оси@y/@x(агрегатор группирует по target). - Переменные:
PERF_TARGETS(glob через запятую; сопоставляется с target без суффикса оси и с полным),PERF_CPU_RATES(1,4,6),PERF_REPEATS(число повторов вместо матричного),PERF_ROLES(rf,admin,dfip),PERF_AXES(y,x),PERF_LOAD_TIMEOUT_MS(ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ),PERF_MAX_STEPS,PERF_TEST_TIMEOUT_MS. - Каждый замер - новый browser context; CPU-троттлинг включается после загрузки данных (до скролла). Перед замером ждём >= 20 строк
tbody tr; если не дождались - записьincomplete: trueсskip_reason. - Метрики: probe (long tasks, кадры),
axis(0 = y, 1 = x),rows_visible_before/after,json_bytes_sheet(размер распакованного ответа загрузки данных из сетевого лога),steps. Trace первого повтора - вperf/results/<run_id>/artifacts/(30-70 МБ каждый, в git не попадают). - Сайт свода не читает
#hashиз URL: вкладка (FORM_1,GO...) выбирается кликом поrole=tab.