From 714f54f008c969aa093e5916031a5086bcb9fc3e Mon Sep 17 00:00:00 2001 From: = <=> Date: Tue, 14 Jan 2025 13:56:10 +0300 Subject: [PATCH] fix(preload): fixed preloading function implementation --- lib/static/modules/utils/imageEntity.ts | 28 +++++++++++++++---- lib/static/modules/utils/index.js | 4 +++ .../components/VisualChecksPage/index.tsx | 9 ++++-- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/lib/static/modules/utils/imageEntity.ts b/lib/static/modules/utils/imageEntity.ts index f8f2b735..f3f8e4c6 100644 --- a/lib/static/modules/utils/imageEntity.ts +++ b/lib/static/modules/utils/imageEntity.ts @@ -1,6 +1,18 @@ -import {preloadImage} from '.'; import {ImageEntity, ImageEntityCommitted, ImageEntityError, ImageEntityFail, ImageEntityStaged, ImageEntitySuccess, ImageEntityUpdated} from '../../new-ui/types/store'; +function preloadImage(url: string): HTMLElement { + const link = document.createElement('link'); + + link.rel = 'preload'; + link.as = 'image'; + link.href = url; + link.onload; + + document.head.appendChild(link); + + return link; +} + function hasExpectedImage(image: ImageEntity): image is ImageEntityFail | ImageEntitySuccess | ImageEntityUpdated { return Object.hasOwn(image, 'expectedImg'); } @@ -13,16 +25,22 @@ function hasDiffImage(image: ImageEntity): image is ImageEntityFail { return Object.hasOwn(image, 'diffImg'); } -export function preloadImageEntity(image: ImageEntity): void { +export function preloadImageEntity(image: ImageEntity): () => void { + const elements: HTMLElement[] = []; + if (hasExpectedImage(image)) { - preloadImage(image.expectedImg.path); + elements.push(preloadImage(image.expectedImg.path)); } if (hasActualImage(image)) { - preloadImage(image.actualImg.path); + elements.push(preloadImage(image.actualImg.path)); } if (hasDiffImage(image)) { - preloadImage(image.diffImg.path); + elements.push(preloadImage(image.diffImg.path)); } + + return (): void => { + elements.forEach(element => element.remove()); + }; } diff --git a/lib/static/modules/utils/index.js b/lib/static/modules/utils/index.js index b68b3997..ebd5b358 100644 --- a/lib/static/modules/utils/index.js +++ b/lib/static/modules/utils/index.js @@ -160,6 +160,10 @@ export function parseKeyToGroupTestsBy(key) { return [groupSection, groupKey]; } +/** @deprecated - this is just not working. + * @link https://stackoverflow.com/questions/3646036/preloading-images-with-javascript + * @see preloadImage from lib/static/modules/utils/imageEntity.ts instead + */ export function preloadImage(url) { new Image().src = url; } diff --git a/lib/static/new-ui/features/visual-checks/components/VisualChecksPage/index.tsx b/lib/static/new-ui/features/visual-checks/components/VisualChecksPage/index.tsx index 2f19f2ce..f2aea92b 100644 --- a/lib/static/new-ui/features/visual-checks/components/VisualChecksPage/index.tsx +++ b/lib/static/new-ui/features/visual-checks/components/VisualChecksPage/index.tsx @@ -36,7 +36,7 @@ export const PRELOAD_IMAGES_COUNT = 3; const usePreloadImages = ( currentNamedImageIndex: number, visibleNamedImageIds: string[]): void => { - const preloaded = useRef>({}); + const preloaded = useRef void | undefined>>({}); const namedImageIdsToPreload: string[] = visibleNamedImageIds.slice( Math.max(0, currentNamedImageIndex - 1 - PRELOAD_IMAGES_COUNT), @@ -51,10 +51,13 @@ const usePreloadImages = ( return; } - preloadImageEntity(image); - preloaded.current[image.id] = true; + preloaded.current[image.id] = preloadImageEntity(image); }); }, [currentNamedImageIndex]); + + useEffect(() => () => { + Object.values(preloaded.current).forEach(preload => preload?.()); + }, []); }; export function VisualChecksPage(): ReactNode {