Maps: canvas renderer for heavy-vector maps (SVG blew Chromium tile memory, tiles vanished)
Viewing a big track (10865-pt, 60km) and zooming/panning threw 'cc/tiles/tile_manager tile memory limits exceeded, some content may not draw' dozens of times - Chromium's compositor tile-memory cap. The track is drawn by Leaflet's default SVG renderer, multi-layered (casing/core + per-1%-slope segments), so the giant SVG layer exceeds the raster budget and the map tiles stop drawing until a force-stop resets the compositor. Set preferCanvas:true on the heavy-vector view maps - showSessionDetail, showRoadsMap (many road polylines, also reported laggy), showComparisonView, showRouteDetail. Canvas draws into one viewport-bounded canvas instead of thousands of SVG paths. Left the recording map on SVG (rotate:true; leaflet-rotate barely supports Canvas) and the route editor (line clicks).
This commit is contained in:
parent
74f3ec4d6e
commit
834204a58a
3 changed files with 35 additions and 5 deletions
|
|
@ -142,7 +142,7 @@
|
|||
### Экраны
|
||||
- **Сегодня** — баланс ккал, еда (продукты + блюда), GPS тренировки, активность, вес, сон, добавки, прогресс-бар жидкости, нутриенты (приход + запасы)
|
||||
- **Продукты** — подтабы [Продукты | Рецепты], поиск, карточки с КБЖУ, добавление в дневник
|
||||
- **Трек** — GPS тренировки (запись с HR), карта с компасом (leaflet-rotate). Навигационный «пак» позиции (SVG divIcon): круг цвета трека (на 20% темнее) с белой + 1px чёрной обводкой + треугольник, указывающий ВВЕРХ (карта и так доворачивается активным источником — курс/компас — вверх, поэтому без покадрового поворота: не трясёт). Мини-компас только в режиме компаса. Z-order панелями: тайлы < дороги(`roadsPane` 240) < маршрут(`routePane` 250) < трек(overlay) < пак(marker). course-up по GPS-курсу (карта и панель доворачиваются в ландшафт вместе, `bearing = h`), ландшафтный режим (CSS rotation), графики скорости/высоты/ЧСС, импорт GPX/FTB, dead reckoning, placeholder до GPS, карта дорог (дедуп 2м, цвета по вело/пешие/бег), сохранённые маршруты (оверлей-навигация, кнопка-тоггл «М», предпросмотр с профилем высоты, топо/уклон-обводка, тоггл «∡/⛰», высоты по цепочке GPXZ→open-elevation→open-meteo→OpenTopoData), де-джиттер трека (Савицкий-Голей, кнопка «≈» на детали), тоггл следования карты за позицией (`followMode`, кнопка `⊕` в `rec-map-btn` стеке; guard вокруг `panTo`/`setView` в `onPoint`/`onBatchUpdate`/`onStateChange`; выкл = свободный просмотр карты на ходу, повторный тап центрирует; не запоминается)
|
||||
- **Трек** — GPS тренировки (запись с HR), карта с компасом (leaflet-rotate). Навигационный «пак» позиции (SVG divIcon): круг цвета трека (на 20% темнее) с белой + 1px чёрной обводкой + треугольник, указывающий ВВЕРХ (карта и так доворачивается активным источником — курс/компас — вверх, поэтому без покадрового поворота: не трясёт). Мини-компас только в режиме компаса. Z-order панелями: тайлы < дороги(`roadsPane` 240) < маршрут(`routePane` 250) < трек(overlay) < пак(marker). course-up по GPS-курсу (карта и панель доворачиваются в ландшафт вместе, `bearing = h`), ландшафтный режим (CSS rotation), графики скорости/высоты/ЧСС, импорт GPX/FTB, dead reckoning, placeholder до GPS, карта дорог (дедуп 2м, цвета по вело/пешие/бег), сохранённые маршруты (оверлей-навигация, кнопка-тоггл «М», предпросмотр с профилем высоты, топо/уклон-обводка, тоггл «∡/⛰», высоты по цепочке GPXZ→open-elevation→open-meteo→OpenTopoData), де-джиттер трека (Савицкий-Голей, кнопка «≈» на детали), тоггл следования карты за позицией (`followMode`, кнопка `⊕` в `rec-map-btn` стеке; guard вокруг `panTo`/`setView` в `onPoint`/`onBatchUpdate`/`onStateChange`; выкл = свободный просмотр карты на ходу, повторный тап центрирует; не запоминается). Карты с тяжёлыми векторами (`showSessionDetail`, `showRoadsMap`, `showComparisonView`, `showRouteDetail`) создаются с `preferCanvas: true` — большой трек/дороги в дефолтном SVG превышают лимит памяти тайлов компоновщика Chromium на зуме (`tile_manager tile memory limits exceeded`) и тайлы гаснут до перезапуска; canvas рисует в один холст. НЕ на карте записи (leaflet-rotate плохо дружит с Canvas) и не в редакторе маршрута (клик по линии)
|
||||
- **Добавки** — 41 нутриент (витамины, минералы, жирные кислоты, женьшень, ресвератрол, CoQ10)
|
||||
- **Настройки** — профиль, образ жизни, нормы ЧСС/давления, BLE пульсометр, велосипеды, GPS конфиг (в т.ч. цвет трека `trackColor`, цвета дорог, GPXZ-ключ), OTA обновления, импорт тайлов, карта дорог
|
||||
|
||||
|
|
|
|||
|
|
@ -47,3 +47,29 @@
|
|||
делал: область products/dedup имела баги (FK), трогать без нужды рискованно. Вынес пользователю
|
||||
на решение.
|
||||
- Тайминг-обвязку (JS [BOOT], Rust [SEED-TIMING]) убрал; lib.rs/main.js вернулись к HEAD.
|
||||
|
||||
## Пропажа тайлов карты на большом треке (отдельный баг)
|
||||
Симптом: смотришь трек 60 км (сессия 1790501377655, 10865 точек), зумишь/таскаешь - тайлы карты
|
||||
пропадают, помогает только force-stop+старт.
|
||||
|
||||
Диагностика по живому logcat (пользователь воспроизвёл: открыл трек -> достроил -> сохранил ->
|
||||
reopen -> убрал достройку -> зум/таскание; буфер предварительно увеличил до 16МБ и очистил):
|
||||
- `E chromium: [ERROR:cc/tiles/tile_manager.cc:1046] tile memory limits exceeded, some content
|
||||
may not draw` - 40+ раз ровно в окно зум/таскания. Это лимит памяти тайлов КОМПОНОВЩИКА
|
||||
Chromium (не карты, не TileCache). Никаких OOM-килла, крахов рендера, CSP по тайлам.
|
||||
- Причина: трек рисуется дефолтным SVG-рендерером Leaflet (`preferCanvas` нигде не задан), да
|
||||
ещё многослойно (casing/core + раскраска по уклону мелкими сегментами). Гигантский SVG-слой на
|
||||
весь трек при зуме превышает бюджет растровой памяти -> компоновщик перестаёт рисовать часть,
|
||||
тайлы гаснут. Force-stop сбрасывает компоновщик. Проявляется на любом крупном треке/карте.
|
||||
|
||||
Фикс (frontend/js/main.js): `preferCanvas: true` на картах с тяжёлыми векторами (canvas рисует
|
||||
в один вьюпортный холст вместо тысяч SVG-путей):
|
||||
- `showSessionDetail` (деталь трека, исходный баг), `showRoadsMap` (карта дорог - много
|
||||
полилиний, пользователь отметил подтормаживания), `showComparisonView` (два трека),
|
||||
`showRouteDetail` (превью маршрута с раскраской).
|
||||
- НЕ трогал: `renderRecordingInline` (там `rotate:true`, а leaflet-rotate почти не поддерживает
|
||||
Canvas - 1 ссылка на L.Canvas против 5 на SVG; canvas+rotate рискован, отдельная проверка),
|
||||
редактор/рисование маршрута (клик/тап по линии, малые полилинии), цель-маркер (без треков).
|
||||
|
||||
Проверка: воспроизвести зум/таскание на треке 60км и на карте дорог, снять logcat, убедиться,
|
||||
что `tile memory limits exceeded` больше НЕ появляется, тайлы держатся.
|
||||
|
|
|
|||
|
|
@ -3807,7 +3807,7 @@ async function showRouteDetail(container, routeId) {
|
|||
if (mapEl) {
|
||||
void mapEl.offsetHeight; // force layout so Leaflet reads the real size
|
||||
L.Icon.Default.imagePath = "lib/";
|
||||
let map = L.map(mapEl, { attributionControl: false, zoomControl: false });
|
||||
let map = L.map(mapEl, { preferCanvas: true, attributionControl: false, zoomControl: false }); // canvas: slope-coloured route vectors vs SVG compositor tile-memory limit
|
||||
map.setView([pts[0].lat, pts[0].lon], 13); // give the map a view NOW so vector layers render (full-page timing)
|
||||
new (TileCache.createLayer())({ maxZoom: 19 }).addTo(map);
|
||||
let routeLayer = drawRoutePolyline(map, pts, route.color, mode);
|
||||
|
|
@ -5402,7 +5402,11 @@ async function showSessionDetail(sessionId) {
|
|||
if (mapEl && points.length) {
|
||||
void mapEl.offsetHeight; // force layout so Leaflet reads the real container size
|
||||
L.Icon.Default.imagePath = "lib/";
|
||||
let map = L.map(mapEl, { attributionControl: false, zoomControl: false, scrollWheelZoom: false, dragging: false, tap: false, touchZoom: true });
|
||||
// preferCanvas: big tracks (10k+ points, multi-layer slope colouring) as SVG blow the
|
||||
// Chromium compositor's tile-memory limit on zoom/pan → map tiles stop drawing until a
|
||||
// restart ("tile memory limits exceeded, some content may not draw"). Canvas renders the
|
||||
// vectors into one viewport-bounded canvas instead of thousands of SVG paths.
|
||||
let map = L.map(mapEl, { preferCanvas: true, attributionControl: false, zoomControl: false, scrollWheelZoom: false, dragging: false, tap: false, touchZoom: true });
|
||||
mapEl._leafletMap = map; // save ref for winStack collapse
|
||||
// Ctrl+wheel zoom on desktop
|
||||
mapEl.addEventListener("wheel", (e) => {
|
||||
|
|
@ -6436,7 +6440,7 @@ async function showComparisonView(currentId, compareId, currentSession, currentP
|
|||
if (btns) btns.style.display = "none";
|
||||
|
||||
L.Icon.Default.imagePath = "lib/";
|
||||
let map = L.map(mapEl, { attributionControl: false, zoomControl: false, touchZoom: true, dragging: true });
|
||||
let map = L.map(mapEl, { preferCanvas: true, attributionControl: false, zoomControl: false, touchZoom: true, dragging: true }); // canvas: two big tracks vs SVG compositor tile-memory limit
|
||||
mapEl._leafletMap = map;
|
||||
addZoomDisplay(map);
|
||||
let CachedLayer = TileCache.createLayer();
|
||||
|
|
@ -8386,7 +8390,7 @@ async function showRoadsMap() {
|
|||
|
||||
let mapEl = document.querySelector("#roads-map");
|
||||
L.Icon.Default.imagePath = "lib/";
|
||||
let map = L.map(mapEl, { attributionControl: false }).setView([47.42, 40.08], 13);
|
||||
let map = L.map(mapEl, { preferCanvas: true, attributionControl: false }).setView([47.42, 40.08], 13); // canvas: many road polylines vs SVG compositor tile-memory limit
|
||||
addZoomDisplay(map);
|
||||
let CachedLayer = TileCache.createLayer();
|
||||
new CachedLayer({ maxZoom: 19 }).addTo(map);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue