React + GoogleMaps 显示标记非常慢

问题描述 投票:0回答:1

我第一次在 React 应用程序中使用 googlemaps,遵循此处的 google 文档:https://developers.google.com/codelabs/maps-platform/maps-platform-101-react-js#0 .

这是一个基本的应用程序,它只是在地图上显示一组坐标的标记图钉,这些坐标全部位于英国境内。这工作正常,直到使用大量数据 - 我必须显示大约 20k-25k 标记。

我正在使用集群,也按照上面的文档。

整个过程持续了大约一分钟,其中浏览器速度非常慢并且经常冻结。我将分享下面的代码,但这几乎是文档中内容的抄本。我愿意以更小的“块”的形式加载数据,比如每隔几秒加载 3000 个引脚,尽管我无法根据文档建议的代码让它工作。

我正在运行节点版本 22.11.0。

任何人都可以帮忙解释为什么这么慢以及改进的方法吗?如果有人能帮忙的话,我很乐意为“请我喝杯咖啡”链接做出贡献。

这是主地图组件:

import { APIProvider, Map } from "@vis.gl/react-google-maps";
import { IMapProps } from "../types";
import MapMarker from "./MapMarker";
const { VITE_GOOGLE_MAPS_API_KEY } = import.meta.env;

const MyMap: React.FC<IMapProps> = ({ mapData }) => {
  return (
    <APIProvider
      apiKey={VITE_GOOGLE_MAPS_API_KEY}
    >
      <div className="w-full relative map-height">
        <Map
          defaultCenter={{ lat: 54.5, lng: -2.0 }}
          defaultZoom={6.3}
          mapId={"639b81a18b67be98"}
        >
          <MapMarker mapData={mapData} />
        </Map>
      </div>
    </APIProvider>
  );
};

export default MyMap;

以及标记代码:

import { useState, useRef, useEffect } from "react";
import { IFormattedData, IMapMarkerProps } from "../types";
import { useMap, AdvancedMarker, Pin } from "@vis.gl/react-google-maps";
import { MarkerClusterer } from "@googlemaps/markerclusterer";
import type { Marker } from "@googlemaps/markerclusterer";

const MapMarker: React.FC<IMapMarkerProps> = ({ mapData }) => {
  const map = useMap();
  const [markers, setMarkers] = useState<{ [key: string]: Marker }>({});
  const clusterer = useRef<MarkerClusterer | null>(null);

  useEffect(() => {
    if (!map) return;
    if (!clusterer.current) {
      clusterer.current = new MarkerClusterer({ map });
    }
  }, [map]);

  useEffect(() => {
    clusterer.current?.clearMarkers();
    clusterer.current?.addMarkers(Object.values(markers));
  }, [markers]);

  const setMarkerRef = (marker: Marker | null, key: string) => {
    if (marker && markers[key]) return;
    if (!marker && !markers[key]) return;
    setMarkers((prev) => {
      if (marker) {
        return { ...prev, [key]: marker };
      } else {
        const newMarkers = { ...prev };
        delete newMarkers[key];
        return newMarkers;
      }
    });
  };

  return (
    <>
      {mapData.map((loc: IFormattedData) => {
        return (
          <AdvancedMarker
            key={loc.key}
            position={loc.location}
            ref={(marker) => setMarkerRef(marker, loc.key)}
            clickable={true}
            title={`CDB Number: ${loc.key}`}
            className="map-marker"
          >
            <Pin
              background={"#cc0099"}
              glyphColor={"#000"}
              borderColor={"#000"}
            />
          </AdvancedMarker>
        );
      })}
    </>
  );
};
export default MapMarker;
reactjs google-maps google-maps-markers
1个回答
0
投票

mapData 从哪里来?循环 25,000 个标记听起来不是一个好主意。我建议从地图中获取当前边界,仅获取边界内的标记,然后循环它们。

<Map
  onBoundsChanged={(bounds) => loadMarkersFromBound(bounds)} >
</Map>

我还建议消除加载函数的抖动,否则当用户在地图上移动时可能会收到太多请求。或者,就像 Airbnb 所做的那样,每当边界发生变化时,您都可以显示一个按钮来手动重新加载新边界的标记。

© www.soinside.com 2019 - 2024. All rights reserved.