feat: add performance monitoring for journey transitions and optimize rendering
- Introduced a new markdown file documenting the optimizations made to the journey motion rendering, including changes to CSS and React components to improve performance on low-end devices. - Implemented a test-only JavaScript file to log layout work during automatic stop changes, tracking metrics such as name resizes, font writes, and heading replacements. - Enhanced the journey rendering by memoizing components and reducing unnecessary re-renders, aligning with web.dev recommendations for animations and layout thrashing prevention.
This commit is contained in:
BIN
artifacts/journey-motion-960x540.jpg
Normal file
BIN
artifacts/journey-motion-960x540.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
37
artifacts/verification-journey-motion.md
Normal file
37
artifacts/verification-journey-motion.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Прокрутка остановок — 11 октября 2026
|
||||
|
||||
Сообщение пользователя: тормозит на Xiaomi Mi Box 4 в Hi Browser в обоих профилях. Устройство не подключено к ADB (список устройств пуст). На физическом Mi Box FPS не измерялся; результат ниже — исходный код, сравнительные счётчики в Codex in-app browser и проверка компоновки.
|
||||
|
||||
## Причина и изменение
|
||||
|
||||
В `src/styles.css` ширина ячеек анимировалась через `flex-basis`. Каждый промежуточный размер вызывал `ResizeObserver` в `FittedDestination`, измерение текста canvas и подбор шрифта с чтением/записью геометрии. Заголовки дополнительно пересоздавались при смене роли «крупный/компактный».
|
||||
|
||||
В `src/NextStops.tsx` выделен мемоизированный `JourneyRail`. Ячейки всегда одинаковой ширины, каждый заголовок имеет два постоянных слоя с заранее подобранным шрифтом. Положение ячеек, увеличение названия и длина линии меняются через `transform`, видимость слоёв — через `opacity`. Коэффициент увеличения согласован со свободным расстоянием до соседней остановки. Анимации ширины, цвета текста и тени маркера удалены. Во время обычного перехода размеры текста не меняются. Тики часов не запускают рендер схемы при неизменных данных; названия, минуты, количество остановок и продолжение сравниваются перед пропуском рендера.
|
||||
|
||||
Это соответствует [рекомендациям web.dev по анимациям](https://web.dev/articles/animations-guide) и [предотвращению повторных синхронных перерасчётов layout](https://web.dev/articles/avoid-large-complex-layouts-and-layout-thrashing). Фактический эффект на GPU конкретного браузера требует проверки на устройстве.
|
||||
|
||||
## Сравнение
|
||||
|
||||
Одинаковый стенд: 960×540, тёмная тема, расстояние «Близко», Автовокзал, фильтр №4. Сохранённое публичное расписание, тестовые часы/погода. Старая производственная сборка сохранена до правки; новая сравнивалась с ней через те же наблюдатели. По три перехода в каждом профиле, окно 1200 мс после смены остановки. Скрипт не меняет прототипы и состояние приложения, не передаёт данные наружу. Счётчики относятся только к названиям остановок, а не ко всему layout или FPS.
|
||||
|
||||
| Профиль / переход | Изменения размеров до → после | Записи шрифта до → после | Замены заголовков до → после |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| ТВ, 1 → 2 | 110 → 0 | 842 → 0 | 2 → 0 |
|
||||
| ТВ, 2 → 3 | 110 → 0 | 632 → 0 | 2 → 0 |
|
||||
| ТВ, 3 → 4 | 110 → 0 | 838 → 0 | 2 → 0 |
|
||||
| Уличное табло, 1 → 2 | 38 → 0 | 82 → 0 | 2 → 0 |
|
||||
| Уличное табло, 2 → 3 | 38 → 0 | 160 → 0 | 2 → 0 |
|
||||
| Уличное табло, 3 → 4 | 38 → 0 | 241 → 0 | 2 → 0 |
|
||||
|
||||
## Поведение
|
||||
|
||||
- Сохранены интервалы 4/6 секунд и движение 900/300 мс для ТВ/уличного профиля. Пауза прекращает смену остановок.
|
||||
- Переход 4 → 1 выполняет мягкое появление, без обратного движения всей схемы.
|
||||
- В промежуточных кадрах ТВ: ширина ячейки постоянна **189,29 px**, высота области названия **51 px**, размер шрифта **41,91 px**. Матрица масштаба меняется 0,871 → 0,984 → 1, зазор до соседней остановки — 24,38 → 27,55 → 28,00 px. Наложения нет.
|
||||
- На конечной демонстрационного маршрута без продолжения: длина линии **0 px**, её начало и центр последнего маркера совпадают (65,797 / 65,796 px). Ложного продолжения нет.
|
||||
- 390×667: длинное название «Больница (Новка)» целиком, высота 72,42 px при доступных 76 px; кружок 22 px.
|
||||
- 1920×1080, три карточки: тот же текст высотой 129,17 px при доступных 239 px; кружок 24 px.
|
||||
- Accessibility показывает по одному названию остановки: второй визуальный слой скрыт через `aria-hidden`.
|
||||
- Настройки и API не расширялись. Режим reduced motion отключает переходы и освобождает подсказки слоёв. Счётчики тестового стенда отсутствуют в production bundle и Docker runtime.
|
||||
|
||||
Проверки: `npm run build` (TypeScript + Vite), 10 тестов маршрута/информационных блоков, синтаксис двух файлов стенда и `git diff --check` прошли. Снимок — `journey-motion-960x540.jpg`. Для обновления серверного табло необходимо развернуть файлы и пересобрать образ.
|
||||
Reference in New Issue
Block a user