Maps: download their three scripts together, and show a spinner until the map is ready
The home, pray and adopt maps ran Mapbox GL, the geocoder and the map bundle one after another, so on a cold first visit the slot stayed empty while ~1.8 MB downloaded in series. Preload hints now fetch all three in parallel (they still run in order), and the slot shows a quiet spinner (aria-busy) until the map element is defined.
This commit is contained in:
parent
aeb61e64f7
commit
a61b1e810a
2 changed files with 37 additions and 4 deletions
|
|
@ -21,6 +21,14 @@ useDoxaMap(props.bundle)
|
|||
const tagName = props.bundle === 'research-map' ? 'doxa-research-map' : 'doxa-map'
|
||||
const isSimple = props.bundle === 'simple-map'
|
||||
|
||||
/* Until the map's element is defined (its scripts are still downloading on a cold first visit),
|
||||
* the slot would be an empty box. Show a quiet spinner instead, so the wait reads as loading. */
|
||||
const ready = ref(false)
|
||||
onMounted(() => {
|
||||
if (typeof customElements === 'undefined') return
|
||||
customElements.whenDefined(tagName).then(() => { ready.value = true })
|
||||
})
|
||||
|
||||
/* With no Mapbox token configured (e.g. a fresh checkout with no .env), the
|
||||
* map would refuse to start ("No Mapbox access token provided"). Ask the
|
||||
* dx-maps bundle for its keyless MapLibre engine instead, as the Research
|
||||
|
|
@ -36,7 +44,8 @@ const effectiveConfig = computed(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="doxa-map-slot">
|
||||
<div class="doxa-map-slot" :aria-busy="ready ? undefined : 'true'">
|
||||
<div v-if="!ready" class="doxa-map-loading" aria-hidden="true"><span class="doxa-map-spinner" /></div>
|
||||
<component :is="tagName" :id="mapId" :profile-config="effectiveConfig" />
|
||||
<div v-if="isSimple" class="doxa-map-scroll-pad doxa-map-scroll-pad--top" />
|
||||
<slot />
|
||||
|
|
@ -44,6 +53,24 @@ const effectiveConfig = computed(() => {
|
|||
</template>
|
||||
|
||||
<style scoped>
|
||||
.doxa-map-loading {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
background: #f2f2f0;
|
||||
z-index: 1;
|
||||
}
|
||||
.doxa-map-spinner {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid rgba(59, 70, 61, 0.2);
|
||||
border-top-color: rgba(59, 70, 61, 0.8);
|
||||
animation: doxa-map-spin 0.9s linear infinite;
|
||||
}
|
||||
@keyframes doxa-map-spin { to { transform: rotate(360deg); } }
|
||||
@media (prefers-reduced-motion: reduce) { .doxa-map-spinner { animation: none; } }
|
||||
.doxa-map-slot {
|
||||
display: block;
|
||||
position: relative;
|
||||
|
|
|
|||
|
|
@ -55,15 +55,21 @@ function loadScript(src: string): Promise<void> {
|
|||
export function useDoxaMap(bundle: BundleKey = 'simple-map') {
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
const MAP_APP_JS = BUNDLES[bundle]
|
||||
|
||||
useHead({
|
||||
link: [
|
||||
{ rel: 'stylesheet', href: 'https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css' },
|
||||
{ rel: 'stylesheet', href: 'https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.css' }
|
||||
{ rel: 'stylesheet', href: 'https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.css' },
|
||||
// The three scripts below still RUN one after another (the map bundle must find
|
||||
// window.mapboxgl), but nothing stops them DOWNLOADING together: without these hints a cold
|
||||
// first visit fetched ~1.8 MB of Mapbox GL, then the geocoder, then the map bundle, in series.
|
||||
{ rel: 'preload', as: 'script', href: MAPBOX_JS },
|
||||
{ rel: 'preload', as: 'script', href: MAPBOX_GEOCODER_JS },
|
||||
{ rel: 'preload', as: 'script', href: MAP_APP_JS }
|
||||
]
|
||||
})
|
||||
|
||||
const MAP_APP_JS = BUNDLES[bundle]
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
// Tell the map bundle which prayer API to fetch from. Must be set before
|
||||
|
|
|
|||
Loading…
Reference in a new issue