How Can I Embed Google Maps Without Slowing Down My Site?

I embedded Google Maps on my website, but it noticeably increased load times and hurt page speed scores. What’s the best way to optimize or lazy-load a Google Maps embed without affecting performance or usability?

Replace the live map with a lightweight placeholder and only create the iframe after the visitor clicks “View map.” Native loading='lazy' helps, but a click-to-load setup prevents Google Maps scripts and network requests from running at all unless someone actually needs the map.

Keep a normal address link below the placeholder so mobile users can open it directly in Google Maps. Give the container a fixed width or aspect ratio to prevent layout shifts, and include a clear button rather than making an unlabeled image clickable.

If you want the quickest improvement, start with:

<iframe
  src='YOUR_EMBED_URL'
  loading='lazy'
  width='600'
  height='450'
  title='Map showing our location'>
</iframe>

For pages where the map is far below the fold, that may be enough. If it appears near the top or page-speed scores still suffer, use the placeholder approach. A static map image is even lighter, but it may require an API key and can create billing or usage-limit concerns.

The hidden trap is loading the placeholder from Google, which can still add another external request and create privacy or consent issues. Use a locally hosted image or plain CSS location card, then inject the iframe only after an explicit click. That makes @nexthub4539’s click-to-load approach much cleaner than relying on loading='lazy', since browsers may fetch lazy iframes before they actually enter the viewport.

First check whether the map is being included in a shared footer or template. If it appears on every page, moving it to the contact/location page will usually matter more than tweaking the iframe. Most visitors do not need an interactive map while reading a blog post or product page. A plain address and “Get directions” link are enough there.

I agree with the click-to-load suggestion, but make sure the iframe has no src at all before the click. Hiding a fully configured iframe with CSS does not prevent the browser from requesting it. Store the URL in data-src, then copy that value into src when the button is activated:

<div class='map-shell'>
  <button type='button' id='load-map'>
    Show interactive map
  </button>

  <iframe
    id='location-map'
    data-src='YOUR_EMBED_URL'
    title='Map showing our location'
    width='600'
    height='450'
    hidden>
  </iframe>
</div>

<script>
  document.getElementById('load-map').addEventListener('click', function () {
    const map = document.getElementById('location-map');
    map.src = map.dataset.src;
    map.hidden = false;
    this.remove();
  }, { once: true });
</script>

I would keep the direct directions link outside that button. Sometimes the better mobile experience is opening the native Maps app, not loading an embedded map and making the user pan around inside a small box. That link still works if JavaScript is blocked or the map fails to load.

If the site uses client-side navigation, remember to remove the iframe when the visitor leaves that page. Otherwise the map can remain alive in the DOM and keep consuming memory even though it is no longer visible. And before spending much time polishing the embed, check whether visitors actually interact with it. If hardly anyone does, an address, directions link, opening hours, and a small local image may be the cleaner answer.

If your embed is only there for an address, drop the map entirely and use a static screenshot linked to Google Maps. @vectorwolfstudio already hinted at this, but I’d go further: most contact pages don’t need an interactive iframe at all, and a plain image plus a directions link kills the performance problem instead of managing it.

Do not add preconnect, dns-prefetch, or a Google Maps script tag to the page if you are using click-to-load. Those “optimizations” start third-party connections before the visitor asks for the map, which weakens the main reason for using a facade in the first place.

The unloaded version should contain exactly this kind of stuff:

  • A local image or simple CSS card
  • The address in real text
  • A button to load the interactive map
  • A normal directions link
  • An iframe with the URL stored in data-src, not src

No hidden map iframe, no Maps JavaScript API, and no external thumbnail pulled from Google. Check the browser’s Network panel before clicking. If requests to Google appear anyway, the map is not actually deferred. Common culprits are page-builder map widgets, tag managers, consent tools, and sitewide scripts added by a theme.

After the click, give the button a visible loading state and disable it until the iframe fires its load event. Otherwise people can click repeatedly and assume the site is broken while the map is downloading. Keep the container at a fixed aspect ratio from the start so the page does not jump when the iframe replaces the placeholder.

I would not load it automatically with IntersectionObserver unless there is a real usability reason. That is better than immediate loading, but it still downloads the map for someone who merely scrolls past it. A deliberate click is the clean cutoff. If requiring a click is considered unacceptable, native loading='lazy' is the low-effort compromise, not the strongest performance fix.

Measure the result properly too. Run the page once with the map removed entirely, then once with the facade. If those results are nearly identical, stop blaming the map and inspect the rest of the page. Large hero images, cookie banners, chat widgets, analytics bundles, and page-builder JavaScript can easily remain the bigger problem. The target should be “no map-related requests before interaction,” not merely a slightly better score.

Check what you’re actually loading.

Some page-builder “Google Maps” blocks load the full Maps JavaScript API, extra plugins, and builder code when all you need is a location pin. Replacing that widget with Google’s basic iframe embed can be a meaningful reduction before adding any lazy-loading setup.

I’d still use the click-to-load method described above for the best initial performance. Just test it after disabling the original widget, since themes and plugins sometimes leave the Maps API script enabled globally even after the visible map is replaced.

The browser Network panel is the quickest sanity check: reload without clicking the placeholder and filter for “maps.” If Google requests are already present, the old integration is still loading somewhere.

Keep the placeholder small. Replacing a heavy map with a 1.5 MB screenshot is the kind of “optimization” that produces a nicer network waterfall but barely improves the actual page.

Use a properly sized local image, preferably WebP or AVIF, with explicit dimensions and a responsive srcset if the map area changes significantly between desktop and mobile. If the placeholder is below the fold, lazy-load that image too. The street address should remain selectable text rather than being baked into the screenshot.

I agree that click-to-load is the strongest option, but it does add friction. Make the first click unambiguous. A button labeled “Load interactive map” sets the right expectation. A screenshot that looks and behaves like a live map until someone clicks it can feel broken because the first click only loads the iframe instead of zooming or opening directions.

There is a reasonable middle ground for pages where the map is central to the task, such as a store locator: load it automatically after the main page finishes and the browser is idle. That will not score as well as explicit click-to-load, but it can be less annoying for users who clearly came for the map. For a normal contact page, though, I would keep the address and directions link immediately usable and treat the interactive map as optional.