Enhance map updates and component performance
- Updated API documentation to clarify the initial data message structure for real-time tile updates. - Modified MapView component to load configuration and user data in parallel, improving map loading speed. - Implemented asynchronous loading for markers after the map is visible, enhancing user experience. - Introduced batching for tile updates to optimize rendering performance during map updates. - Refactored character and marker creation functions to utilize dynamic Leaflet imports, improving modularity.
This commit is contained in:
@@ -271,9 +271,12 @@ onMounted(async () => {
|
||||
|
||||
const L = (await import('leaflet')).default
|
||||
|
||||
const [charactersData, mapsData] = await Promise.all([
|
||||
// Load maps, characters, config and me in parallel so map can show sooner.
|
||||
const [charactersData, mapsData, config, user] = await Promise.all([
|
||||
api.getCharacters().then((d) => (Array.isArray(d) ? d : [])).catch(() => []),
|
||||
api.getMaps().then((d) => (d && typeof d === 'object' ? d : {})).catch(() => ({})),
|
||||
api.getConfig().catch(() => ({})) as Promise<ConfigResponse>,
|
||||
api.me().catch(() => null) as Promise<MeResponse | null>,
|
||||
])
|
||||
|
||||
const mapsList: MapInfo[] = []
|
||||
@@ -295,9 +298,7 @@ onMounted(async () => {
|
||||
maps.value = mapsList
|
||||
mapsLoaded.value = true
|
||||
|
||||
const config = (await api.getConfig().catch(() => ({}))) as ConfigResponse
|
||||
if (config?.title) document.title = config.title
|
||||
const user = (await api.me().catch(() => null)) as MeResponse | null
|
||||
auths.value = user?.auths ?? config?.auths ?? []
|
||||
|
||||
const initialMapId =
|
||||
@@ -328,6 +329,7 @@ onMounted(async () => {
|
||||
document.addEventListener('contextmenu', contextMenuHandler, true)
|
||||
|
||||
layersManager = createMapLayers({
|
||||
L,
|
||||
map: leafletMap,
|
||||
markerLayer: mapInit.markerLayer,
|
||||
layer: mapInit.layer,
|
||||
@@ -382,16 +384,25 @@ onMounted(async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// Show map as soon as canvas and layers are ready; markers load in background.
|
||||
if (leafletMap) leafletMap.invalidateSize()
|
||||
nextTick(() => {
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
if (leafletMap) leafletMap.invalidateSize()
|
||||
mapReady.value = true
|
||||
})
|
||||
if (leafletMap) leafletMap.invalidateSize()
|
||||
mapReady.value = true
|
||||
})
|
||||
})
|
||||
|
||||
intervalId = setInterval(() => {
|
||||
// Markers load asynchronously after map is visible.
|
||||
api.getMarkers().then((body) => {
|
||||
layersManager!.updateMarkers(Array.isArray(body) ? body : [])
|
||||
questGivers.value = layersManager!.getQuestGivers()
|
||||
})
|
||||
|
||||
const CHARACTER_POLL_MS = 4000
|
||||
const CHARACTER_POLL_MS_HIDDEN = 30000
|
||||
|
||||
function pollCharacters() {
|
||||
api
|
||||
.getCharacters()
|
||||
.then((body) => {
|
||||
@@ -400,24 +411,37 @@ onMounted(async () => {
|
||||
players.value = layersManager!.getPlayers()
|
||||
mapLive.value = list.some((c) => c.ownedByMe)
|
||||
})
|
||||
.catch(() => clearInterval(intervalId!))
|
||||
}, 2000)
|
||||
.catch(() => {
|
||||
if (intervalId) clearInterval(intervalId)
|
||||
intervalId = null
|
||||
})
|
||||
}
|
||||
|
||||
api.getMarkers().then((body) => {
|
||||
layersManager!.updateMarkers(Array.isArray(body) ? body : [])
|
||||
questGivers.value = layersManager!.getQuestGivers()
|
||||
})
|
||||
function startCharacterPoll() {
|
||||
if (intervalId) clearInterval(intervalId)
|
||||
const ms =
|
||||
typeof document !== 'undefined' && document.visibilityState === 'hidden'
|
||||
? CHARACTER_POLL_MS_HIDDEN
|
||||
: CHARACTER_POLL_MS
|
||||
pollCharacters()
|
||||
intervalId = setInterval(pollCharacters, ms)
|
||||
}
|
||||
|
||||
startCharacterPoll()
|
||||
if (import.meta.client) {
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
startCharacterPoll()
|
||||
})
|
||||
}
|
||||
|
||||
watch(mapLogic.state.showGridCoordinates, (v) => {
|
||||
if (mapInit?.coordLayer) {
|
||||
;(mapInit.coordLayer.options as { visible?: boolean }).visible = v
|
||||
mapInit.coordLayer.setOpacity(v ? 1 : 0)
|
||||
mapInit.coordLayer.redraw?.()
|
||||
if (v && leafletMap) {
|
||||
mapInit.coordLayer.bringToFront?.()
|
||||
mapInit.coordLayer.redraw?.()
|
||||
leafletMap.invalidateSize()
|
||||
} else {
|
||||
mapInit.coordLayer.redraw?.()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user