5.1 KiB
5.1 KiB
План рефакторинга критических проблем в клиентской части
Введение
Этот план фокусируется на 3 самых критических проблемах, выявленных в анализе:
- BOM в main.js - Может сломать загрузку app.
- Race conditions в router guards - Неправильные redirects и access leaks.
- Memory leaks в composables - Утечки памяти от timers/WS.
План пошаговый, с оценкой effort. После фиксов - manual testing. Timeline: 4-6 часов.
1. Удаление BOM в main.js
Описание
Невидимый BOM-символ (EF BB BF) в начале файла приводит к SyntaxError в парсинге JS.
Приоритет: High (App crash)
Влияние: Полный отказ загрузки в некоторых браузерах/builds.
Шаги реализации
- Открыть
client/src/main.jsв редакторе с hex-view (VSCode + Hex Editor extension). - Удалить первые 3 байта (BOM).
- Сохранить как UTF-8 without BOM (VSCode: File > Save with Encoding > UTF-8).
- Проверить: Нет перед import.
Затронутые файлы
client/src/main.js
Effort: Low (15 мин)
Тестирование
npm run dev- No console errors.npm run build && npm run preview- App mounts correctly.- Open in browser: Inspect source - no BOM.
2. Fix race conditions в router guards
Описание
reauth() в beforeEach синхронный, но может быть async (WS/API) - guard не ждет, leading to wrong next().
Приоритет: High (Security/UX)
Влияние: Access to / without auth, infinite redirects.
Шаги реализации
- В
useAuth.js: Сделать reauth async:const reauth = async () => { if (user.value) return true; const localData = localStorage.getItem('user_data'); if (localData) { user.value = JSON.parse(localData); return true; } try { await apiReauth(); return !!user.value; } catch { return false; } }; - В
router/index.js: Async guard:router.beforeEach(async (to, from, next) => { try { const isAuth = await reauth(); if (to.meta.requiresAuth && !isAuth) { next('/login'); return; } if (to.meta.requiresGuest && isAuth) { next('/'); return; } next(); } catch (error) { console.error('Router error:', error); next('/login'); } }); - Добавить global loading в App.vue:
<template> <div v-if="loadingAuth">Loading...</div> <RouterView v-else /> </template> <script setup> const { loadingAuth } = useAuth(); </script>
Затронутые файлы
client/src/composables/useAuth.jsclient/src/router/index.jsclient/src/App.vue
Effort: Medium (1 час)
Тестирование
- Clear localStorage, navigate / - redirect to /login.
- Slow network (DevTools): No access to HomePage until reauth done.
- Login -> / - no loop.
3. Cleanup в composables (Fix memory leaks)
Описание
Timers (setInterval), WS connections, watchers не очищаются onUnmounted.
Приоритет: High (Performance)
Влияние: Memory leaks в long sessions, ghost WS.
Шаги реализации
- В каждом composable (useWebSocket, useTime, useGamePorts, etc.):
- Import
onUnmountedfrom 'vue'. - В setup:
let intervalId; onUnmounted(() => { if (intervalId) clearInterval(intervalId); if (ws) ws.close(); // Cleanup watchers: unwatch(); });
- Import
- Для WS-specific (useWebSocket.js):
- В connect:
ws.onclose = () => { clearTimeout(heartbeat); }; - В sendMessage: AbortController для timeout cleanup.
- В connect:
- Для global (useWebSocketGlobal.js): Track active components, cleanup on last unmount.
- Добавить в useAuth/logout: Cleanup WS if global.
Затронутые файлы
client/src/composables/useWebSocket.jsclient/src/composables/useWebSocketGlobal.jsclient/src/composables/useTime.jsclient/src/composables/game/useGamePorts.jsclient/src/composables/shift/useShiftOperations.js- Другие composables с timers/watch
Effort: Medium (2-3 часа, multiple files)
Тестирование
- Navigate Login <-> Home multiple times.
- DevTools > Memory: Heap snapshot - no growth.
- Network: No duplicate WS connects on route change.
- Long run (5+ min): No console spam from ghosts.
Заключение
- Общий timeline: 3-4 часа (High first).
- Commit strategy: Separate commits: "Fix BOM in main.js", "Async router guards", "Cleanup composables".
- Post-fix: Full manual test: Auth, navigate, WS actions (start game, shift open), memory check.
- Риски: Low - isolated changes. Backup branch перед.
Файл создан: plans/client-critical-refactor-plan.md.