- number-поля теперь рендерятся как text + inputMode=numeric, чтобы браузер не округлял значения через input type=number - пробелы при вставке в number-поля удаляются - бэкенд нормализует значения number-полей в строку перед сохранением - добавлен хелпер normalizeFieldValueForStorage Closes: искажение расчётного счёта и других длинных числовых полей
82 lines
4.2 KiB
Plaintext
82 lines
4.2 KiB
Plaintext
ДИАГНОСТИКА ПРОБЛЕМ:
|
||
|
||
1️⃣ FormEditor.tsx — 6 последовательных/параллельных запросов создают dead time 300-600ms
|
||
└─ Каждый запрос к form, fields, statuses, transitions, tabs, users блокирует рендеринг
|
||
└─ Пользователь видит пустой экран пока все 6 Promise'ов не завершены
|
||
|
||
2️⃣ TaskView.tsx — N+1 антипаттерн (51 запрос для 50 задач)
|
||
└─ 1 запрос: список задач
|
||
└─ 50 запросов: для каждой задачи загружаются поля, связи, данные таблиц
|
||
└─ При latency 250ms = 12.75 сек на загрузку таблицы
|
||
└─ Экспоненциальный рост: 100 задач → 101 запрос
|
||
|
||
3️⃣ Отсутствие staleTime — данные перезапрашиваются при каждом открытии
|
||
└─ Справочные данные (статусы, пользователи, поля) редко меняются
|
||
└─ Каждое открытие dropdown = новый запрос
|
||
└─ staleTime=0 (default) → React Query не кэширует данные
|
||
|
||
---
|
||
|
||
ОЦЕНКА ПРЕДЛОЖЕННОГО РЕШЕНИЯ:
|
||
|
||
✅ ЧТО ПРАВИЛЬНО:
|
||
• /api/forms/:id/editor (6 → 1 запрос) — срез 300-600ms
|
||
• /api/forms/:id/tasks/with-fields (51 → 1 запрос) — решение N+1
|
||
• staleTime для селектов — необходимо для справочников
|
||
• Обновление компонентов — правильный follow-up
|
||
|
||
⚠️ ЧТО НУЖНО УЛУЧШИТЬ:
|
||
|
||
1. НЕДОСТАТОК: Нет gcTime (ранее cacheTime)
|
||
РЕШЕНИЕ: gcTime: 10*60*1000 → данные будут в памяти 10 минут
|
||
РЕЗУЛЬТАТ: Повторный вход на страницу за 10 минут = без запроса
|
||
|
||
2. НЕДОСТАТОК: Нет retry/refetchOnWindowFocus стратегии
|
||
РЕШЕНИЕ: Добавить retry: 1, refetchOnWindowFocus: 'stale'
|
||
РЕЗУЛЬТАТ: Более надёжная обработка сетевых ошибок
|
||
|
||
3. НЕДОСТАТОК: Если /api/forms/:id/editor упадёт — весь FormEditor сломается
|
||
РЕШЕНИЕ: Error boundary или fallback на параллельные запросы
|
||
РЕЗУЛЬТАТ: Более graceful degradation
|
||
|
||
4. НЕДОСТАТОК: Нет pagination для больших списков задач
|
||
РЕШЕНИЕ: /api/forms/:id/tasks/with-fields?page=0&limit=50
|
||
РЕЗУЛЬТАТ: Контролируемый payload, не 10MB за раз
|
||
|
||
5. НЕДОСТАТОК: Нет инвалидации кэша при изменениях
|
||
РЕШЕНИЕ: В mutation'ах queryClient.invalidateQueries({ queryKey: ['tasks', formId] })
|
||
РЕЗУЛЬТАТ: Консистентность данных после create/update/delete
|
||
|
||
---
|
||
|
||
МЕТРИКИ УЛУЧШЕНИЯ:
|
||
|
||
ТЕКУЩЕЕ СОСТОЯНИЕ:
|
||
• FormEditor: 300-600ms (6 запросов)
|
||
• TaskView (50 задач): 12-15 сек (51 запрос)
|
||
• Повторные открытия: 100% перезагрузка
|
||
|
||
ПОСЛЕ РЕАЛИЗАЦИИ:
|
||
• FormEditor: 100-150ms (1 запрос)
|
||
• TaskView (50 задач): 200-300ms (1 запрос)
|
||
• Повторные открытия: <10ms (кэш)
|
||
|
||
РЕЗУЛЬТАТ: 3-50x раз быстрее (в зависимости от сценария)
|
||
|
||
---
|
||
|
||
ПРИОРИТЕТ РЕАЛИЗАЦИИ:
|
||
|
||
1. HIGH: /api/forms/:id/editor (максимальный выигрыш)
|
||
2. HIGH: /api/forms/:id/tasks/with-fields (решает N+1)
|
||
3. MEDIUM: staleTime + gcTime для селектов
|
||
4. MEDIUM: Pagination для больших списков
|
||
5. LOW: Error handling (улучшение стабильности)
|
||
|
||
---
|
||
|
||
ДОПОЛНИТЕЛЬНЫЕ ОПТИМИЗАЦИИ:
|
||
• React Suspense для прогрессивного рендеринга (React 18+)
|
||
• Server-Driven UI для FormEditor
|
||
• Мониторить Network tab — size, timing, redundant requests
|