diff --git a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx index 68f8905f267..8a5ae9ee78c 100644 --- a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx +++ b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx @@ -2,9 +2,12 @@ import React from 'react'; import { useEnvironment } from '../contexts'; import { descriptors, Flex, Image, useAppearance } from '../customizables'; +import type { InternalTheme } from '../foundations'; import type { PropsOfComponent } from '../styledSystem'; import { RouterLink } from './RouterLink'; +const logoLoadCache: { [url: string]: boolean } = {}; + const getContainerHeightForImageRatio = (imageRef: React.RefObject, width: string) => { if (!imageRef.current) { return `calc(${width} * 2)`; @@ -23,13 +26,20 @@ const getContainerHeightForImageRatio = (imageRef: React.RefObject; -export const ApplicationLogo = (props: ApplicationLogoProps) => { +export const ApplicationLogo = React.memo((props: ApplicationLogoProps) => { const imageRef = React.useRef(null); - const [loaded, setLoaded] = React.useState(false); const { logoImageUrl, applicationName, homeUrl } = useEnvironment().displayConfig; const { parsedLayout } = useAppearance(); const imageSrc = parsedLayout.logoImageUrl || logoImageUrl; const logoUrl = parsedLayout.logoLinkUrl || homeUrl; + const [loaded, setLoaded] = React.useState(() => (imageSrc ? logoLoadCache[imageSrc] || false : false)); + + const handleImageLoad = React.useCallback(() => { + if (imageSrc) { + logoLoadCache[imageSrc] = true; + setLoaded(true); + } + }, [imageSrc]); if (!imageSrc) { return null; @@ -42,7 +52,7 @@ export const ApplicationLogo = (props: ApplicationLogoProps) => { alt={applicationName} src={imageSrc} size={200} - onLoad={() => setLoaded(true)} + onLoad={handleImageLoad} sx={{ display: loaded ? 'inline-block' : 'none', height: '100%', @@ -57,7 +67,7 @@ export const ApplicationLogo = (props: ApplicationLogoProps) => { elementDescriptor={descriptors.logoBox} {...props} sx={[ - theme => ({ + (theme: InternalTheme) => ({ height: getContainerHeightForImageRatio(imageRef, theme.sizes.$6), justifyContent: 'center', }), @@ -78,4 +88,4 @@ export const ApplicationLogo = (props: ApplicationLogoProps) => { )} ); -}; +});