refactor: Optimize map component rendering and memoize functions to improve performance

This commit is contained in:
2025-09-17 08:29:51 +02:00
parent 0bb0b07429
commit 1a49919000

View File

@@ -94,22 +94,8 @@ function ProjectsMapPageContent() {
setMeasurementLine(null); setMeasurementLine(null);
}; };
// Wrapper component for the map with proper loading state // Status configuration with colors and labels - memoized
const MapWrapper = React.useMemo(() => { const statusConfig = React.useMemo(() => ({
return function MapWrapperComponent(props) {
return (
<Suspense fallback={<MapLoadingComponent t={t} />}>
<DynamicMap
{...props}
isMeasuring={isMeasuring}
measurementPoints={measurementPoints}
onMeasurementClick={addMeasurementPoint}
/>
</Suspense>
);
};
}, [t, isMeasuring, measurementPoints, addMeasurementPoint]);
const statusConfig = {
registered: { registered: {
color: "#6B7280", color: "#6B7280",
label: formatProjectStatus("registered"), label: formatProjectStatus("registered"),
@@ -135,7 +121,7 @@ function ProjectsMapPageContent() {
label: formatProjectStatus("cancelled"), label: formatProjectStatus("cancelled"),
shortLabel: "Wycofany", shortLabel: "Wycofany",
}, },
}; }), []);
// Toggle all status filters // Toggle all status filters
const toggleAllFilters = () => { const toggleAllFilters = () => {
@@ -160,12 +146,12 @@ function ProjectsMapPageContent() {
})); }));
}; };
// Layer control functions // Layer control functions - memoized to prevent re-renders
const handleBaseLayerChange = (layerName) => { const handleBaseLayerChange = React.useCallback((layerName) => {
setActiveBaseLayer(layerName); setActiveBaseLayer(layerName);
}; }, []);
const toggleOverlay = (layerName) => { const toggleOverlay = React.useCallback((layerName) => {
setActiveOverlays((prev) => { setActiveOverlays((prev) => {
if (prev.includes(layerName)) { if (prev.includes(layerName)) {
return prev.filter((name) => name !== layerName); return prev.filter((name) => name !== layerName);
@@ -173,14 +159,14 @@ function ProjectsMapPageContent() {
return [...prev, layerName]; return [...prev, layerName];
} }
}); });
}; }, []);
const toggleLayerPanel = () => { const toggleLayerPanel = React.useCallback(() => {
setShowLayerPanel(!showLayerPanel); setShowLayerPanel(!showLayerPanel);
}; }, [showLayerPanel]);
// Update URL with current map state (debounced to avoid too many updates) // Update URL with current map state (debounced to avoid too many updates)
const updateURL = (center, zoom) => { const updateURL = React.useCallback((center, zoom) => {
const params = new URLSearchParams(); const params = new URLSearchParams();
params.set("lat", center[0].toFixed(6)); params.set("lat", center[0].toFixed(6));
params.set("lng", center[1].toFixed(6)); params.set("lng", center[1].toFixed(6));
@@ -188,10 +174,10 @@ function ProjectsMapPageContent() {
// Use replace to avoid cluttering browser history // Use replace to avoid cluttering browser history
router.replace(`/projects/map?${params.toString()}`, { scroll: false }); router.replace(`/projects/map?${params.toString()}`, { scroll: false });
}; }, [router]);
// Handle map view changes with debouncing // Handle map view changes with debouncing - memoized
const handleMapViewChange = (center, zoom) => { const handleMapViewChange = React.useCallback((center, zoom) => {
setMapCenter(center); setMapCenter(center);
setMapZoom(zoom); setMapZoom(zoom);
@@ -200,7 +186,7 @@ function ProjectsMapPageContent() {
window.mapUpdateTimeout = setTimeout(() => { window.mapUpdateTimeout = setTimeout(() => {
updateURL(center, zoom); updateURL(center, zoom);
}, 500); // Wait 500ms after the last move to update URL }, 500); // Wait 500ms after the last move to update URL
}; }, [updateURL]);
// Hide navigation and ensure full-screen layout // Hide navigation and ensure full-screen layout
useEffect(() => { useEffect(() => {
@@ -298,8 +284,9 @@ function ProjectsMapPageContent() {
} }
}, [currentTool, isMeasuring]); }, [currentTool, isMeasuring]);
// Convert projects to map markers with filtering // Convert projects to map markers with filtering - memoized to prevent re-renders
const markers = projects const markers = React.useMemo(() => {
return projects
.filter((project) => project.coordinates) .filter((project) => project.coordinates)
.filter((project) => statusFilters[project.project_status] !== false) .filter((project) => statusFilters[project.project_status] !== false)
.map((project) => { .map((project) => {
@@ -419,6 +406,7 @@ function ProjectsMapPageContent() {
}; };
}) })
.filter((marker) => marker !== null); .filter((marker) => marker !== null);
}, [projects, statusFilters, statusConfig, t]);
if (loading) { if (loading) {
return ( return (
@@ -980,7 +968,7 @@ function ProjectsMapPageContent() {
</div> </div>
) : ( ) : (
<div className="absolute inset-0"> <div className="absolute inset-0">
<MapWrapper <DynamicMap
center={mapCenter} center={mapCenter}
zoom={mapZoom} zoom={mapZoom}
markers={markers} markers={markers}