6 Min. Lesezeit

Google Maps API optimieren: wie ich die Rechnung auf ein Fünftel gesenkt habe

Google MapsAPIOptimisationPerformanceJavaScript
Google Maps API optimieren: wie ich die Rechnung auf ein Fünftel gesenkt habe

Das Problem: eine Rechnung, die bei jedem Traffic-Peak explodiert

VoglioMap ist eine interaktive Karte, die Voglio-Bene-Händler weltweit lokalisiert. Bei jedem Besuch lädt der Browser die Karte, ortet den Nutzer, geokodiert seine Adresse, berechnet Routen und zeigt Marker an. Multipliziere das mit ein paar Hundert Besuchern pro Monat - und die Google-Maps-Rechnung steigt schnell.

Am Anfang lag ich bei rund 250 €/Monat. Nicht katastrophal, aber unnötig: Die meisten dieser Aufrufe waren redundant. Mit ein paar gezielten Optimierungen bin ich unter 50 €/Monat gekommen - also -80% - ohne Funktionsverlust.

Hier sind die 4 Techniken, die den Unterschied gemacht haben.

1. Geocoding in der Datenbank cachen

Geocoding (eine Adresse in GPS-Koordinaten umwandeln) ist der teuerste Aufruf der Maps API. Und gleichzeitig der häufigste: jedes Mal, wenn ein neuer Händler hinzugefügt wird, jedes Mal, wenn du Adressen bei einem Besuch erneut geokodierst.

Aber eine Adresse ändert sich nicht jeden Tag.

Ich habe eine Tabelle geocode_cache in MySQL angelegt:

CREATE TABLE geocode_cache (
    address_hash VARCHAR(64) PRIMARY KEY,
    address TEXT,
    lat DECIMAL(10, 7),
    lng DECIMAL(10, 7),
    geocoded_at DATETIME
);

Vor jedem Aufruf der Geocoding API berechne ich den SHA-256-Hash der normalisierten Adresse und prüfe, ob sie bereits im Cache liegt. Wenn ja, gebe ich die gespeicherten Koordinaten zurück. Wenn nein, rufe ich Google auf, speichere das Ergebnis und nutze es für alle zukünftigen Anfragen wieder.

Ergebnis: 95% der Geocoding-Aufrufe eliminiert. Die Rechnung auf dieser Position ist von ~80 €/Monat auf ~5 €/Monat gefallen.

2. Rate Limiting auf öffentlichen Endpunkten

Ohne Rate Limiting kann jeder dein Frontend zumüllen (ein Script, das die Seite neu lädt, ein böswilliger Bot) und die Rechnung in wenigen Stunden in die Höhe treiben. Meiner Seite ist das einmal passiert - und die böse Überraschung kam auf der Rechnung im Folgemonat.

Ich habe ein Middleware auf PHP-Seite hinzugefügt:

function checkRateLimit($ip) {
    $key = "rate:$ip";
    $count = apcu_fetch($key) ?: 0;
    if ($count >= 60) return false; // max. 60 Anfragen / Stunde
    apcu_store($key, $count + 1, 3600);
    return true;
}

60 Anfragen pro IP und Stunde reichen für menschliche Nutzung locker aus und blockieren Missbrauch. Ich habe außerdem auf API-Seite einen Check für sensible Endpunkte (Suche, Navigation) ergänzt, mit niedrigerem Schwellwert (10/h für die Navigation).

Ergebnis: seitdem keine ungewöhnlichen Peaks mehr. Die Rechnung ist planbar geworden.

3. Lazy Loading der Marker und Clustering

Alle Marker auf einmal zu rendern, wenn du ein paar Hundert davon hast, überlastet den Browser und löst mehr API-Aufrufe aus. Die Lösung: nur die im Viewport sichtbaren Marker laden.

Ich nutze das bounds_changed-Event von Google Maps, um die sichtbaren Koordinaten zu holen, und fetche dann die Marker in diesem Bereich. Auf der Server-Seite ist es ein simples WHERE lat BETWEEN x AND y AND lng BETWEEN x AND y - schnell mit Spatial Indexes.

Ich habe außerdem den MarkerClusterer aktiviert: Statt 200 einzelne Marker beim Rauszoomen anzuzeigen, werden sie in nummerierte Cluster gruppiert. Viel lesbarer, und deutlich weniger DOM zu verwalten.

Ergebnis: weniger Aufrufe von places.nearbySearch() und eine Seite, die selbst mit vielen Händlern flüssig bleibt.

4. Static Maps für nicht-interaktive Ansichten

Nicht jede Seite braucht eine interaktive Karte. Auf den einzelnen Händlerseiten zum Beispiel will der Nutzer nur den Standort sehen - er wird nicht zoomen oder explorieren.

Für diese Fälle habe ich das JavaScript-Embed durch die Static Maps API ersetzt, die ein PNG-Bild zurückgibt. Die Kosten sind pro Aufruf ~10x niedriger und das Laden geht auch schneller (ein simples Bild vs. ein JS-Script, das die Karte initialisiert).

<img src="https://maps.googleapis.com/maps/api/staticmap?
    center=43.6108,3.8767
    &zoom=14
    &size=400x300
    &markers=color:red%7C43.6108,3.8767
    &key=YOUR_API_KEY"
/>

Bonus: die Bilder werden vom Browser gecached, also bedeutet ein erneuter Besuch derselben Seite = null neue Aufrufe.

Ergebnis: ~30% der JavaScript-Aufrufe wurden zu Static Maps, ~10x günstiger.

Die Bilanz in Zahlen

PostenVorherNachher
Geocoding API80 €/Monat5 €/Monat
Maps JavaScript API130 €/Monat30 €/Monat
Places API40 €/Monat8 €/Monat
Gesamt250 €/Monat43 €/Monat

Und die Nutzererfahrung? Keine sichtbare Verschlechterung. Im Gegenteil, die Seite lädt schneller (Static Maps + Lazy-Loading der Marker) und ist gegen Missbrauch geschützt.

Was ich daraus mitnehme

Die Google Maps API ist nicht teuer im Absoluten - sie ist teuer per Default, weil sie keinerlei Optimierung für dich macht. Du zahlst jeden Aufruf, ob nützlich oder redundant.

Cachen, Rate Limiting, Lazy Loading: das sind Basics, aber bei Standard-Implementierungen werden sie selten umgesetzt. Wenn du von einer nicht optimierten Karte ausgehst, ist eine Drittelung oder Fünftelung deiner Rechnung wahrscheinlich nur ein paar Stunden Entwicklungsarbeit entfernt.

Und falls dein Traffic eines Tages explodiert: deine Optimierungen schützen dich vor dem Preisschock. Auch das ist ROI.