Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions src/components/src/map/layer-hover-info.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project

import React, {useMemo} from 'react';
import React, {useEffect, useRef, useMemo} from 'react';
import styled from 'styled-components';
import truncate from 'lodash/truncate';
import {CompareType, Field, Merge, TooltipField} from '@kepler.gl/types';
Expand Down Expand Up @@ -69,6 +69,33 @@

const TOOLTIP_VALUE_MAX_LENGTH = 256;

/**
* Image component that cleans up resources on unmount to prevent memory leaks.
* Revokes blob/object URLs and clears the image src to release memory.
*/
const TooltipImage: React.FC<{src: string}> = ({src}) => {
const imgRef = useRef<HTMLImageElement>(null);

useEffect(() => {
return () => {
// Revoke blob URLs to free memory
if (src && (src.startsWith('blob:') || src.startsWith('data:'))) {
try {
URL.revokeObjectURL(src);
} catch (e) {
// ignore errors from non-object URLs
}
}
// Clear the image src to release the decoded image from memory
if (imgRef.current) {
imgRef.current.src = '';

Check warning on line 91 in src/components/src/map/layer-hover-info.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

The ref value 'imgRef.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'imgRef.current' to a variable inside the effect, and use that variable in the cleanup function
}
};
}, [src]);

return <img ref={imgRef} src={src} />;
};

const Row: React.FC<RowProps> = ({name, value, deltaValue, url}) => {
// Set 'url' to 'value' if it looks like a url
if (!url && value && typeof value === 'string' && value.match(/^http/)) {
Expand All @@ -86,7 +113,7 @@
<td className="row__name">{asImg ? name.replace('<img>', '') : name}</td>
<td className="row__value">
{asImg ? (
<img src={value} />
<TooltipImage src={value} />
) : url ? (
<a target="_blank" rel="noopener noreferrer" href={url}>
{displayValue}
Expand Down