Optimised iframe buffering on AdminX (#18064)

no issue

- Added a little delay to allow for a bit more time to load before
swapping.
- Also fixed a little bug where the array condition in the memo is
returning false.


---

<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 6cce5d7</samp>

Improved the loading behavior of the admin settings page by adding a
delay before showing the iframes. Fixed a typo in the `data-testid`
attribute of `IframeBuffering.tsx`.
This commit is contained in:
Ronald Langeveld 2023-09-11 20:29:04 +07:00 committed by GitHub
parent fec67c8d2a
commit 1aa9dffbec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 11 deletions

View File

@ -68,6 +68,7 @@ const AnnouncementBarPreview: React.FC<AnnouncementBarSettings> = ({announcement
return (
<div className='h-screen w-screen overflow-hidden'>
<IframeBuffering
addDelay={true}
className="absolute left-0 top-0 h-full w-full"
generateContent={injectContentIntoIframe}
height='100%'
@ -79,6 +80,21 @@ const AnnouncementBarPreview: React.FC<AnnouncementBarSettings> = ({announcement
);
};
function arraysAreEqual(arr1: string[], arr2: string[]) {
if (!arr1 || !arr2) {
return arr1 === arr2;
} // handles null or undefined values
if (arr1.length !== arr2.length) {
return false;
}
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) {
return false;
}
}
return true;
}
export default memo(AnnouncementBarPreview, (prevProps, nextProps) => {
// Check if announcementBackgroundColor changed
if (prevProps.announcementBackgroundColor !== nextProps.announcementBackgroundColor) {
@ -96,7 +112,7 @@ export default memo(AnnouncementBarPreview, (prevProps, nextProps) => {
}
// Check if visibility array changed in size or content
if (prevProps.visibility !== nextProps.visibility) {
if (!arraysAreEqual(prevProps.visibility || [], nextProps.visibility || [])) {
return false;
}

View File

@ -7,30 +7,45 @@ type IframeBufferingProps = {
height?: string;
width?: string;
testId?: string;
addDelay?: boolean;
};
const IframeBuffering: React.FC<IframeBufferingProps> = ({generateContent, className, height, width, parentClassName, testId}) => {
const IframeBuffering: React.FC<IframeBufferingProps> = ({generateContent, className, height, width, parentClassName, testId, addDelay = false}) => {
const [visibleIframeIndex, setVisibleIframeIndex] = useState(0);
const iframes = [useRef<HTMLIFrameElement>(null), useRef<HTMLIFrameElement>(null)];
useEffect(() => {
const invisibleIframeIndex = visibleIframeIndex === 0 ? 1 : 0;
const iframe = iframes[invisibleIframeIndex].current;
if (iframe) {
// Start generating the content for the invisible iframe
generateContent(iframe);
// Attach a load listener to the iframe
const onLoad = () => {
// Once content is loaded, introduce a delay before swapping visibility
if (addDelay) {
setTimeout(() => {
setVisibleIframeIndex(invisibleIframeIndex);
}, 500); // 500ms delay
} else {
setVisibleIframeIndex(invisibleIframeIndex);
}
};
iframe.addEventListener('load', onLoad);
return () => {
// Cleanup: Remove the event listener to prevent memory leaks
iframe.removeEventListener('load', onLoad);
};
}
const timer = setTimeout(() => {
setVisibleIframeIndex(invisibleIframeIndex);
}, 100);
return () => {
clearTimeout(timer);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [generateContent]);
return (
<div className={parentClassName} data-testId={testId}>
<div className={parentClassName} data-testid={testId}>
<iframe
ref={iframes[0]}
className={`${className} ${visibleIframeIndex !== 0 ? 'z-10 opacity-0' : 'z-20 opacity-100'}`}