En esta guía, se proporciona un análisis detallado de los componentes web de mapas en 3D y las consideraciones que debes tener en cuenta cuando los integres en tu aplicación.
Consideraciones de rendimiento
Para garantizar una experiencia fluida y responsiva para la interactividad y los elementos visuales, considera los siguientes enfoques.
Carga el mapa
La configuración inicial de carga y renderización de los mapas en 3D combina técnicas de configuración del navegador y prácticas recomendadas de IU para brindar una experiencia del usuario óptima.
- Carga de la API: Usa la carga dinámica asíncrona de los mapas en 3D para cargar la API de Maps JavaScript en la carga inicial de la página.
- Bibliotecas: Carga bibliotecas de manera programática donde sea necesario, como
google.maps.importLibrary("maps3d"). Como alternativa, si usas componentes web como<gmp-map-3d>directamente en tu página HTML con la carga directa de secuencias de comandos, las bibliotecas se cargarán automáticamente en el momento adecuado. - Administra los componentes del mapa base: Usa un mapId personalizado para filtrar los lugares de interés del mapa base (modo HYBRID) y controlar su densidad, en especial si la aplicación tiene su propio conjunto de elementos personalizados, como marcadores o polilíneas. Esto evita el desorden visual y la posible superposición. Como alternativa, puedes inhabilitar las funciones de las tarjetas vectoriales del mapa base, como los lugares de interés, las polilíneas de las rutas, los nombres de las rutas y los nombres de las calles (modo SATÉLITE).
- Eventos: Escucha los eventos gmp-steadystate o gmp-error para compilar tu lógica posterior, como cargar marcadores o animar la cámara.
Interacción del usuario: Espera el evento gmp-steadystate antes de realizar cambios en el contenido del mapa. Si un usuario comienza a interactuar (desplazamiento, zoom) con el mapa antes del evento gmp-steadystate inicial, el evento solo se activará después de que el usuario deje de interactuar. Evita mostrar o actualizar contenido superpuesto (como marcadores o polígonos) mientras el usuario se desplaza por el mapa o lo acerca o aleja. Para ello, escucha los eventos gmp-centerchange, gmp-headingchange, gmp-rangechange, gmp-rollchange y gmp-tiltchange.
Usa
requestAnimationFrame()(rAF) para las actualizaciones continuas y separa estrictamente los cálculos intensivos de las llamadas de dibujo.- Usa rAF: Sincroniza las actualizaciones con la frecuencia de visualización del navegador para obtener una animación fluida de 60 FPS y un consumo de energía reducido.
- Evita el trabajo de dibujo intensivo: No realices tareas pesadas que no sean de dibujo durante la actualización final.
- Separa la lógica: Realiza toda la lógica intensiva antes de las llamadas de actualización mínimas de los componentes web dentro del bucle rAF.
Configuración inicial de la escena:
<gmp-map-3d>Los parámetros de configuración de la cámara, como la inclinación, afectarán la velocidad de carga. Cuanto más se acerque o se incline la escena, más polígonos detallados se mostrarán y se deberán cargar. El nivel de detalle también dependerá de la ubicación (p.ej., una ciudad con muchos edificios en comparación con un campo con solo elementos naturales).Precargador visual: Si bien
<gmp-map-3d>se carga con mucha rapidez, es posible que tarde un poco en mostrarse en resolución completa para los usuarios con dispositivos de gama baja (GPU baja) o ancho de banda bajo (4G lento). En este caso, puedes crear un precargador con una imagen, una animación o un texto con la escena en 3D que se carga en segundo plano. Consulta el evento clave que debes usar a continuación:
// create the map in the background and wait for gmp-steadystate event async function initMap() { await google.maps.importLibrary("maps3d"); const map = document.querySelector('gmp-map-3d'); const div = document.querySelector('div'); // preloader " map.addEventListener('gmp-steadystate', ({isSteady}) => { if (isSteady) { div.style.display = 'none'; } }); } initMap();
- Mapa en 2D:
- A estos usuarios, se les puede mostrar un mapa 2D alternativo (SATELLITE) que incluya tus datos geográficos, como los marcadores.
- Como alternativa, se puede mostrar un mapa estático complementario en 2D en el modo SATÉLITE para que los usuarios visualicen un lugar determinado mientras se carga.
Rendimiento y administración de los elementos visuales
Los mapas en 3D ofrecen varias formas de mostrar elementos visuales, como marcadores, polilíneas y modelos en 3D, con un rendimiento óptimo y un tiempo de renderización mínimo, incluso para los elementos visuales de mayor volumen.
Marcadores
- Opción de personalización óptima:
- PinElement: Para realizar cambios básicos en los marcadores (color, escala, borde, glifo de texto), usa el elemento
<gmp-pin>o la clasePinElement. Este es el método de personalización con mejor rendimiento. - Usa marcadores HTMLImageElement o SVGElement con moderación: Úsalos para obtener más opciones de personalización, como agregar transparencia o insertar una imagen, como un ícono, en un SVGElement (requiere codificación base64). Se rasterizarán durante la carga y generarán una sobrecarga de rendimiento. HTMLImageElement y SVGElement deben unirse en el elemento
<template>antes de asignarse al espacio predeterminado de Marker3DElement. - Por el momento, no se puede agregar HTML o CSS sin formato.
- PinElement: Para realizar cambios básicos en los marcadores (color, escala, borde, glifo de texto), usa el elemento
- Administra el comportamiento de colisión: Aprovecha la propiedad collisionBehavior del marcador. Para los marcadores críticos que siempre deben estar visibles, configura el comportamiento según corresponda. En el caso de los marcadores menos importantes, permite que se oculten para mantener una experiencia de mapa más limpia y menos desordenada, especialmente en niveles de zoom altos.
- Solo para lugares de interés críticos: Solo usa drawsWhenOccluded (o establece la propiedad de manera programática) para los marcadores que deben verse a través de edificios o terrenos (p.ej., un objetivo de rescate, una línea de servicios públicos enterrada o el avatar de un usuario).
- Prueba la oclusión: Como el mapa es en 3D, los marcadores pueden quedar ocultos visualmente (ocluirse) por edificios o el terreno. Prueba diferentes ángulos de cámara y altitudes de marcadores para garantizar que los lugares de interés cruciales permanezcan visibles o implementa una lógica para ajustar la visibilidad y la altitud cuando se oculten.
- Aprovecha la altitud: En los mapas en 3D, los marcadores deben usar la posición con un valor de altitud. En el caso de los marcadores asociados con el terreno o los edificios, usa altitudeMode: 'RELATIVE_TO_GROUND', 'RELATIVE_TO_MESH' o parámetros de configuración similares para asegurarte de que el marcador se fije correctamente cuando se incline o rote el mapa.
Polígonos y polilíneas
- Simplifica la geometría: Antes de renderizar, aplica un algoritmo de simplificación a tus datos de ruta de acceso. Esto reduce la cantidad de vértices, pero conserva la forma general, lo que mejora drásticamente la velocidad de renderización, en especial para límites o rutas complejos.
- Diezmado por nivel de zoom: En el caso de conjuntos de datos muy grandes, considera cargar geometría con mayor nivel de detalle solo cuando el usuario acerque el mapa al área. En un nivel de zoom bajo, solo se necesita una versión muy simplificada de la polilínea o el polígono.
- Cálculo previo para polígonos extruidos: Si tus polígonos están extruidos (
extruded: true), los datos de la ruta definen un volumen 3D (una malla). El procesamiento de polígonos complejos con muchos vértices es costoso desde el punto de vista computacional. Asegúrate de que los datos de origen de tus polígonos sean lo más simples posible. - Prueba el rendimiento de las polilíneas y los polígonos: Cuando agregues polilíneas o polígonos numerosos o complejos, en especial cuando se extruyan para 3D, asegúrate de que no causen caídas en la velocidad de fotogramas. Limita la cantidad de vértices o usa algoritmos de simplificación si es necesario.
- Cuando actualices una forma, modifica todo el array de rutas en una sola operación, en lugar de crear un bucle y modificar elementos individuales. Una sola operación de asignación (p.ej., polyline.path = newPathArray;) es mucho más eficiente que varias actualizaciones iterativas.
- Evita las polilíneas extruidas (siempre que sea posible): Si bien las polilíneas pueden usar un valor de altitud para ubicarse en un espacio 3D, extruir una polilínea (p.ej., asignarle un ancho de trazo y un intervalo de altitud grande) puede requerir un uso intensivo de gráficos. Siempre que sea posible, usa polilíneas 2D en el suelo (RELATIVE_TO_GROUND) o un ancho de trazo mínimo para mejorar el rendimiento.
- Usa drawsOccludedSegments solo para los elementos de ruta críticos. En el caso de las formas de fondo o contextuales, permite que la geometría 3D del mapa las oculte de forma natural. Mostrar geometría oculta no crítica agrega una complejidad de renderización innecesaria.
Modelos 3D
La renderización y la interactividad del modelo .glb en 3D, como el evento de clic gmp, son muy rápidas en <gmp-map-3d>.
- Minimiza el tamaño de los archivos con compresión: Para garantizar una carga rápida, en especial en redes móviles, mantén los archivos de modelos .glb complejos por debajo de los 5 MB (lo ideal es que sean más pequeños). El método principal para lograrlo es aplicar la compresión de Draco en los datos de malla de tus archivos .glb, lo que puede reducir significativamente el tamaño del archivo (a menudo, en más del 50%) con una pérdida mínima de calidad visual.
- Centra el origen del modelo: Asegúrate de que el software de modelado 3D exporte el modelo con su origen (punto 0, 0, 0) centrado en la base del modelo. Esto simplifica el posicionamiento y la rotación en el mapa, lo que garantiza que el modelo se fije correctamente en las coordenadas de latitud y longitud.
- Administra el CORS: Si los archivos de tu modelo se alojan en un dominio o una CDN diferentes de los de tu aplicación web, debes configurar el servidor de hosting para que incluya los encabezados de uso compartido de recursos de origen cruzado (CORS) necesarios (p.ej., Access-Control-Allow-Origin: *). De lo contrario, el mapa no podrá cargar el modelo.