perf: optimization for maps & network

This commit is contained in:
2026-02-26 12:39:15 -05:00
parent ba7631dc9c
commit 7b3141e5e9
5 changed files with 299 additions and 28 deletions

View File

@ -1,5 +1,5 @@
/** Composable for Google Maps integration */
import { ref, onMounted } from 'vue'
import { ref, shallowRef, onMounted } from 'vue'
import { setOptions, importLibrary } from '@googlemaps/js-api-loader'
const getApiKey = () => import.meta.env.VITE_GOOGLE_MAPS_API_KEY || ''
@ -10,7 +10,7 @@ let mapsLoaded = false
const globalOverlays = new Map<google.maps.Map, Set<google.maps.Marker | google.maps.Polyline>>()
export function useGoogleMaps() {
const map = ref<google.maps.Map | null>(null)
const map = shallowRef<google.maps.Map | null>(null)
const isLoaded = ref(false)
const error = ref<string | null>(null)
@ -234,6 +234,73 @@ export function useGoogleMaps() {
return polyline
}
async function addRoutePolyline(paradas: Array<{ lat: number; lng: number }>) {
if (!map.value) {
console.error('Map not initialized')
return []
}
if (!paradas || paradas.length < 2) {
console.warn("Se necesitan al menos 2 paradas para trazar una ruta.");
return []
}
const directionsService = new google.maps.DirectionsService();
const renderizadoresActivos: google.maps.DirectionsRenderer[] = [];
const tamañoChunk = 25;
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
for (let i = 0; i < paradas.length - 1; i += (tamañoChunk - 1)) {
const chunk = paradas.slice(i, i + tamañoChunk);
if (chunk.length < 2) break;
const origen = { lat: chunk[0]!.lat, lng: chunk[0]!.lng };
const destino = { lat: chunk[chunk.length - 1]!.lat, lng: chunk[chunk.length - 1]!.lng };
const waypoints = chunk.slice(1, -1).map(p => ({
location: { lat: p.lat, lng: p.lng },
stopover: true
}));
const request = {
origin: origen,
destination: destino,
waypoints: waypoints,
travelMode: google.maps.TravelMode.DRIVING,
optimizeWaypoints: false
};
try {
const response = await directionsService.route(request);
const renderer = new google.maps.DirectionsRenderer({
map: map.value,
suppressMarkers: true,
preserveViewport: true, // Siempre conservar la vista ya que trazamos fragmentos
polylineOptions: {
strokeColor: '#0057FF', // Azul
strokeWeight: 4,
strokeOpacity: 0.8
}
});
renderer.setDirections(response);
renderizadoresActivos.push(renderer);
// Registrar en global overlays para limpiarlos después
if (!globalOverlays.has(map.value)) {
globalOverlays.set(map.value, new Set())
}
globalOverlays.get(map.value)!.add(renderer as any);
} catch (error) {
console.error(`Error trazando el tramo (Paradas ${i} a ${i + chunk.length}):`, error);
}
await delay(200);
}
return renderizadoresActivos;
}
function fitBounds(path: Array<{ lat: number; lng: number }>) {
if (!map.value || path.length === 0) {
return
@ -378,6 +445,7 @@ export function useGoogleMaps() {
addHtmlMarker,
addNumberedMarker,
addPolyline,
addRoutePolyline,
fitBounds,
setCenter,
setZoom,