perf(map): reuse resources across routes
Preserve standard network layers between map pages while disposing route-owned overlays and controls to prevent memory growth.
This commit is contained in:
@@ -14,8 +14,21 @@ import mapboxStreets from "@assets/map/layers/mapbox-streets.png";
|
||||
import clsx from "clsx";
|
||||
import { MAPBOX_TOKEN, TIANDITU_TOKEN } from "@config/config";
|
||||
import type { Map as OlMap } from "ol";
|
||||
import { markMapResourcePersistent } from "../mapLifecycle";
|
||||
|
||||
const INITIAL_LAYER = "mapbox-light";
|
||||
const BASE_LAYER_METADATA = [
|
||||
{ id: "mapbox-light", name: "默认地图", img: mapboxLight.src },
|
||||
{ id: "mapbox-satellite", name: "卫星地图", img: mapboxSatellite.src },
|
||||
{
|
||||
id: "mapbox-satellite-streets",
|
||||
name: "卫星街道地图",
|
||||
img: mapboxSatelliteStreet.src,
|
||||
},
|
||||
{ id: "mapbox-streets", name: "街道地图", img: mapboxStreets.src },
|
||||
{ id: "tianditu-vector", name: "天地图矢量", img: mapboxOutdoors.src },
|
||||
{ id: "tianditu-image", name: "天地图影像", img: mapboxSatellite.src },
|
||||
] as const;
|
||||
|
||||
const createTileLayer = (url: string, attributions: string) =>
|
||||
new TileLayer({
|
||||
@@ -77,46 +90,37 @@ const createBaseLayerEntries = () => {
|
||||
|
||||
return [
|
||||
{
|
||||
id: "mapbox-light",
|
||||
name: "默认地图",
|
||||
...BASE_LAYER_METADATA[0],
|
||||
layer: lightMapLayer,
|
||||
img: mapboxLight.src,
|
||||
},
|
||||
{
|
||||
id: "mapbox-satellite",
|
||||
name: "卫星地图",
|
||||
...BASE_LAYER_METADATA[1],
|
||||
layer: satelliteLayer,
|
||||
img: mapboxSatellite.src,
|
||||
},
|
||||
{
|
||||
id: "mapbox-satellite-streets",
|
||||
name: "卫星街道地图",
|
||||
...BASE_LAYER_METADATA[2],
|
||||
layer: satelliteStreetsLayer,
|
||||
img: mapboxSatelliteStreet.src,
|
||||
},
|
||||
{
|
||||
id: "mapbox-streets",
|
||||
name: "街道地图",
|
||||
...BASE_LAYER_METADATA[3],
|
||||
layer: streetsLayer,
|
||||
img: mapboxStreets.src,
|
||||
},
|
||||
{
|
||||
id: "tianditu-vector",
|
||||
name: "天地图矢量",
|
||||
...BASE_LAYER_METADATA[4],
|
||||
layer: new Group({
|
||||
layers: [tiandituVectorLayer, tiandituVectorAnnotationLayer],
|
||||
}),
|
||||
img: mapboxOutdoors.src,
|
||||
},
|
||||
{
|
||||
id: "tianditu-image",
|
||||
name: "天地图影像",
|
||||
...BASE_LAYER_METADATA[5],
|
||||
layer: new Group({
|
||||
layers: [tiandituImageLayer, tiandituImageAnnotationLayer],
|
||||
}),
|
||||
img: mapboxSatellite.src,
|
||||
},
|
||||
];
|
||||
].map((entry) => ({
|
||||
...entry,
|
||||
layer: markMapResourcePersistent(entry.layer),
|
||||
}));
|
||||
};
|
||||
|
||||
const BaseLayers: React.FC = () => {
|
||||
@@ -158,11 +162,7 @@ const BaseLayers: React.FC = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const baseLayers = useMemo(() => createBaseLayerEntries().map(({ id, name, img }) => ({
|
||||
id,
|
||||
name,
|
||||
img,
|
||||
})), []);
|
||||
const baseLayers = BASE_LAYER_METADATA;
|
||||
|
||||
const handleQuickSwitch = () => {
|
||||
const nextId =
|
||||
@@ -194,6 +194,15 @@ const BaseLayers: React.FC = () => {
|
||||
}, 300);
|
||||
};
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
if (hideTimer.current) {
|
||||
clearTimeout(hideTimer.current);
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="absolute right-17 bottom-11 z-20">
|
||||
<div
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import { useMap } from "../MapComponent";
|
||||
import { ScaleLine } from "ol/control";
|
||||
import { markMapResourcePersistent } from "../mapLifecycle";
|
||||
|
||||
const Scale: React.FC = () => {
|
||||
const map = useMap();
|
||||
@@ -31,14 +32,16 @@ const Scale: React.FC = () => {
|
||||
updateZoomLevel();
|
||||
|
||||
// ScaleLine control
|
||||
const scaleControl = new ScaleLine({
|
||||
target: scaleLineRef.current || undefined,
|
||||
units: "metric",
|
||||
bar: false,
|
||||
steps: 4,
|
||||
text: true,
|
||||
minWidth: 64,
|
||||
});
|
||||
const scaleControl = markMapResourcePersistent(
|
||||
new ScaleLine({
|
||||
target: scaleLineRef.current || undefined,
|
||||
units: "metric",
|
||||
bar: false,
|
||||
steps: 4,
|
||||
text: true,
|
||||
minWidth: 64,
|
||||
}),
|
||||
);
|
||||
map.addControl(scaleControl);
|
||||
|
||||
return () => {
|
||||
|
||||
Reference in New Issue
Block a user