Mobile Development 10 min read

Hybrid Native Map and H5 Integration via WebView for Overseas Projects

The project replaces costly Google Dynamic Maps with a hybrid solution that overlays a transparent WebView on a native map component, using a JSBridge to route H5 events and native map interactions, dynamically managing hot‑zone data, thereby cutting service fees, boosting performance, and preserving H5 development flexibility.

HelloTech
HelloTech
HelloTech
Hybrid Native Map and H5 Integration via WebView for Overseas Projects

Background: The current overseas project relies on Google Maps services for map-related capabilities. The H5 side uses Google Dynamic Maps, which is a paid service and accounts for a significant portion of overseas revenue. Initial optimizations reduced Dynamic Maps cost by about 50%, but further reduction is needed.

As the business evolves, native maps show clear performance advantages over web maps, especially in first‑screen experience.

Target Value

Eliminate Google Maps web‑side service fees to reduce costs.

Improve user experience and close the performance gap with competing map solutions.

Maintain H5 development flexibility without maintaining two separate core business codebases.

Design Scheme

The solution adopts a hybrid approach: use a WebView to host H5 pages while rendering the map with a native map component. This allows normal H5 event handling and native map event dispatch.

Initial ideas of multiple WebViews stacked over a native map were discarded due to memory isolation, performance waste, and high refactor cost.

After evaluating industry practices, a React‑based integration was implemented.

Framework Design

1. Fusion Scheme Design

Page architecture diagram:

Fusion technology architecture diagram:

Data communication flow diagram:

Expected effects:

Click events on H5 elements inside the WebView are handled by the WebView container.

Map interactions are dispatched to the native map component.

JSBridge enables communication between native map and WebView layers.

Core Idea: The page consists of a native map layer plus a transparent WebView layer placed on top. Hot‑zone data is provided by the web side; the native side distinguishes hot zones to route events appropriately. JSBridge handles data and event exchange.

Hot‑Zone Data and Coordinates

The origin (0,0) is defined at the top‑left corner of the WebView. Hot‑zone coordinates follow the format [left, top, width, height] relative to the WebView.

Dynamic Updates

Hot zones may change dynamically, requiring runtime updates. The core code for registering a hot zone is:

import Bridge from '@/Bridge'
const getHotData = (data: number[]) => {
  // ...
  return [0,0,100,100]
}
useEffect(() => {
  if (cardRef.current) {
    // Get DOM element info
    const rect = cardRef.current.getBoundingClientRect();
    // Convert to coordinate format
    const coordinates = getHotData(rect)
    // Pass to native via Bridge
    Bridge.setHotZoneInfo(coordinates)
  }
}, [cardRef]);

Full‑screen elements (e.g., popups) are observed using MutationObserver to detect DOM changes. The observer configuration:

const width = document.documentElement.clientWidth || document.body.clientWidth;
const height = document.documentElement.clientHeight || document.body.clientHeight;
const clientRect = Dom.getBoundingClientRect();
const isFull = clientRect.width === width && clientRect.height === height;
const config: MutationObserverInit = {
  attributes: true, // observe attribute changes
  attributeOldValue: true,
  childList: true, // observe added/removed child nodes
  subtree: true, // observe all descendants
  attributeFilter: ['id', 'class', 'style'],
};

Callback handling mutations:

let elementPath = [] // track full‑screen elements
const callback = (mutationsList: MutationRecord[], observer: MutationObserver) => {
  try {
    for (const mutation of mutationsList) {
      const { target, type, attributeName, addedNodes } = mutation;
      if (type === 'childList') {
        let tag = false;
        if (addedNodes.length) {
          // ...
        } else {
          // ...
        }
      } else if (type === 'attributes') {
        if (attributeName === 'class') {
          // ...
        } else {
          // attribute change handling
        }
      }
    }
  } catch (e) {
    // fallback to H5 map on error
  }
};

The callback determines whether a full‑screen H5 element exists; if so, it notifies the native side via Bridge to let the WebView handle gestures, otherwise the hot‑zone logic applies.

Testing Tools

A lightweight vConsole plugin was built to invoke Bridge methods and test hot zones. Hot zones are visualized on a Canvas for quick diagnosis.

The overall practice integrates WebView and native components, improving development iteration speed for overseas business while ensuring high‑quality map experience. It also reduces reliance on full app releases for map updates.

mobile developmentHybrid AppReactWebViewJSBridgeHotzoneNative Map
HelloTech
Written by

HelloTech

Official Hello technology account, sharing tech insights and developments.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.