← Back to list

Improving Map Performance in React Native: A Deck.GL + WebView Approach

When building mobile applications with React Native, rendering large numbers of data points and shapes on maps can become a major…

Narayanan Ramanathan · 2025-09-01 10:52 · 1 claps · 3.9 min read
#react-native #google-maps #performance-improvement #react #deckgl
Open on Medium ↗
Wiki topics: 🌐 · Web Development 📱 · Mobile Development

Improving Map Performance in React Native: A Deck.GL + WebView Approach

When building mobile applications with React Native, rendering large numbers of data points and shapes on maps can become a major bottleneck — especially when using libraries like [react-native-maps](https://www.npmjs.com/package/react-native-maps). In our case, the performance on mobile devices degraded significantly, making the map nearly unusable for end users.

In this article, I’ll walk you through the problem we faced, the solution we implemented, and why it worked — complete with a real-world example.

The Problem: Performance Bottlenecks in react-native-maps

We initially built our map feature using react-native-maps, a popular choice for adding map functionality in React Native apps. It worked well for basic use cases. However, once we started loading thousands of data points and complex shapes (like polygons), the performance took a hit:

  • Slow rendering of markers and polygons.
  • Laggy map interaction (panning, zooming).
  • In some devices, the app would even freeze momentarily.

Here’s a simplified version of what we were doing:

<MapView
  style={{ flex: 1 }}
  initialRegion={{
    latitude: 37.78825,
    longitude: -122.4324,
    latitudeDelta: 0.0922,
    longitudeDelta: 0.0421,
  }}
>
  {dataPoints.map(point => (
    <Marker
      key={point.id}
      coordinate={{ latitude: point.lat, longitude: point.lng }}
      title={point.name}
    />
  ))}
{shapes.map(shape => (
    <Polygon
      key={shape.id}
      coordinates={shape.coordinates}
      strokeColor="#000"
      fillColor="rgba(255,0,0,0.5)"
    />
  ))}
</MapView>

Despite optimizations like clustering and throttling, we hit a ceiling on what react-native-maps could handle smoothly.

The Solution: Offloading to WebView with Google Maps + Deck.GL

To solve this, we took a hybrid approach:

Step 1: Build a Web Page Using Google Maps + Deck.GL

We created a standalone web page that uses:

  • Google Maps JavaScript API for the base map.
  • Deck.GL for rendering large datasets efficiently.

Deck.GL, developed by Uber, is a WebGL-powered framework optimized for visualizing large-scale geospatial data. It handles GPU rendering, so performance remains smooth even with thousands of points or complex layers.

Here’s a snippet of the core idea in our web page:

const deckgl = new deck.DeckGL({
  mapStyle: 'https://xxxx/style.json',
  initialViewState: {
    longitude: -122.4,
    latitude: 37.8,
    zoom: 10,
  },
  controller: true,
  layers: [
    new deck.ScatterplotLayer({
      id: 'scatter-layer',
      data: largeDataset,
      getPosition: d => [d.longitude, d.latitude],
      getFillColor: [255, 0, 0],
      getRadius: 100,
      pickable: true,
      onClick: info => {
        if (info.object) {
          window.ReactNativeWebView.postMessage(JSON.stringify({
            type: 'POINT_SELECTED',
            payload: info.object,
          }));
        }
      }
    }),
    new deck.PolygonLayer({
      id: 'polygon-layer',
      data: shapes,
      getPolygon: d => d.coordinates,
      getFillColor: [0, 0, 255, 100],
      pickable: true,
      onClick: info => {
        if (info.object) {
          window.ReactNativeWebView.postMessage(JSON.stringify({
            type: 'POLYGON_SELECTED',
            payload: info.object,
          }));
        }
      }
    })
  ]
});

window.ReactNativeWebView.postMessage(...) is how we send data from the web page to the React Native app.

Step 2: Load the Web Page in a WebView

In the React Native app, we used the built-in WebView component to render this web page:

import React, { useRef } from 'react';
import { WebView } from 'react-native-webview';

const MapScreen = () => {
  const webviewRef = useRef();

  const handleMapMessage = (event) => {
    try {
      const message = JSON.parse(event.nativeEvent.data);
      if (message.type === 'POINT_SELECTED') {
        console.log('Selected Point:', message.payload);
        // Handle point selection (e.g., open details modal)
      } else if (message.type === 'POLYGON_SELECTED') {
        console.log('Selected Polygon:', message.payload);
        // Handle shape interaction
      }
    } catch (e) {
      console.warn('Invalid message from WebView', e);
    }
  };

  return (
    <WebView
      ref={webviewRef}
      source={{ uri: 'https://your-map-page.com' }}
      onMessage={handleMapMessage}
      javaScriptEnabled={true}
      originWhitelist={['*']}
    />
  );
};

Step 3: Send Data from React Native to the WebView

To communicate between the native app and the WebView, we used custom events and script injection.

// React Native side
const sendMapData = (data) => {
  const script = `
    window.dispatchEvent(new CustomEvent('MapDataEvent', {
      detail: ${JSON.stringify(data)}
    }));
  `;
  webviewRef.current.injectJavaScript(script);
};

On the web page, we listened for the custom event:

window.addEventListener('MapDataEvent', (event) => {
  const { points, polygons } = event.detail;
  // Update Deck.GL layers dynamically
  updateMapLayers(points, polygons);
});

Example Use Case

Let’s say a user taps a polygon on the map (e.g., a city boundary). The web page detects this using Deck.GL’s onClick, and sends the selected polygon’s data back to React Native:

{
  "type": "POLYGON_SELECTED",
  "payload": {
    "id": "zone_12",
    "name": "Downtown Area",
    "coordinates": [...]
  }
}

The app then can:

  • Show detailed info in a modal.
  • Navigate to a new screen.
  • Trigger analytics/logging.

Why This Worked

  1. GPU-Accelerated Rendering Deck.GL leverages WebGL to render layers on the GPU, unlike react-native-maps which mostly uses native UI components.
  2. WebView Isolation By offloading heavy rendering tasks to a WebView, we reduced the computational load on the React Native thread.
  3. Flexibility with Data Updates Dynamic data injection allows seamless updates to map content without reloading the page or the WebView.

Real-World Impact

After implementing this solution:

  • Rendering thousands of points and complex shapes became smooth.
  • Frame rate and responsiveness improved drastically.
  • End users experienced almost no lag, even on older devices.

This hybrid approach gave us the best of both worlds: the flexibility and integration of React Native, with the performance and rendering power of web-based tools.

If you’re struggling with performance issues when rendering complex maps in React Native, consider leveraging a WebView-based solution using Google Maps and Deck.GL. It might feel like a workaround, but in many real-world use cases, it’s a pragmatic and powerful strategy.

Let me know if you’ve faced similar challenges or tried other approaches — I’d love to hear what worked for you!

References & Resources

Other reads:

🔔 Follow me for more practical frontend development tips! 👏 If you found this useful, don’t forget to clap!


메타데이터
post_id
6baf22d422eb
slug
improving-map-performance-in-react-native-a-deck-gl-webview-approach-6baf22d422eb
url
https://medium.com/@nramanathan_21774/improving-map-performance-in-react-native-a-deck-gl-webview-approach-6baf22d422eb
canonical_url
https://medium.com/@nramanathan_21774/improving-map-performance-in-react-native-a-deck-gl-webview-approach-6baf22d422eb
author_url
https://medium.com/@nramanathan_21774
status
ok
fetched_at
2026-07-17 20:23:32