feat: add image preloading functionality in BlogIndexProvider for optimized loading of cover images
All checks were successful
CI - Build and Push / Build and Push Docker Image (push) Successful in 20s
All checks were successful
CI - Build and Push / Build and Push Docker Image (push) Successful in 20s
This commit is contained in:
@@ -5,6 +5,22 @@ import type { BlogPostSummary, BlogTag } from '../blog/types';
|
||||
|
||||
export const BLOG_INDEX_PAGE_SIZE = 6;
|
||||
|
||||
const prefetchedImages = new Set<string>();
|
||||
|
||||
function preloadImage(url: string) {
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!url || prefetchedImages.has(url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const img = new Image();
|
||||
img.src = url;
|
||||
prefetchedImages.add(url);
|
||||
}
|
||||
|
||||
interface BlogIndexContextValue {
|
||||
initialPosts: BlogPostSummary[];
|
||||
initialTotalCount: number;
|
||||
@@ -76,6 +92,28 @@ export function BlogIndexProvider({ children }: { children: ReactNode }) {
|
||||
[initialPosts, initialTotalCount, initialTags, isLoading, error, hasInitialData],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasInitialData) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
const urls = initialPosts
|
||||
.map((post) => post.coverImageUrl)
|
||||
.filter((url): url is string => Boolean(url));
|
||||
|
||||
// Avoid re-prefetching the same set to prevent needless work
|
||||
const needsPrefetch = urls.some((url) => !prefetchedImages.has(url));
|
||||
if (!needsPrefetch) {
|
||||
return;
|
||||
}
|
||||
|
||||
urls.forEach(preloadImage);
|
||||
}, [initialPosts, hasInitialData]);
|
||||
|
||||
return <BlogIndexContext.Provider value={value}>{children}</BlogIndexContext.Provider>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user