Skip to content

Feat: Implement lazy loading for images in gallery to improve performanceΒ #983

@Muneerali199

Description

@Muneerali199

Is there an existing issue for this?

  • I have searched the existing issues

What happened?

πŸ“‹ Issue Title

Feat: Implement lazy loading for images in gallery to improve performance


πŸ“– Description

Currently, all images in the gallery load immediately when the page renders, which can cause:

  • Slow initial page load times
  • High memory usage with large galleries
  • Poor performance on slower network connections
  • Unnecessary bandwidth consumption for images not in viewport

Problem Statement

When a user opens a gallery with hundreds or thousands of images, all images start loading at once. This leads to:

  1. Performance Issues: Browser struggles to handle multiple simultaneous image requests
  2. Poor UX: Users see loading spinners everywhere instead of a smooth experience
  3. Bandwidth Waste: Images below the fold load even if users never scroll to them
  4. Memory Issues: Large galleries consume excessive RAM

🎯 Expected Behavior

Images should load progressively using the Intersection Observer API:

  • Only images visible in the viewport should load initially
  • Images should load as the user scrolls down
  • Show skeleton/placeholder while images load
  • Implement a small buffer (load images slightly before they enter viewport)

πŸ’‘ Proposed Solution

Implementation Plan:

  1. Create a LazyImage Component

    • Use Intersection Observer API
    • Add loading state with skeleton placeholder
    • Support error states with fallback image
    • Progressive image loading (low quality β†’ high quality)
  2. Update Image Components

    • Replace <img> tags in ImageCard.tsx with <LazyImage>
    • Update ChronologicalGallery.tsx to use lazy loading
    • Ensure thumbnail images also lazy load
  3. Add Configuration Options

    • Configurable root margin (e.g., "200px" to preload)
    • Configurable threshold
    • Option to disable lazy loading for small galleries

Technical Details:

interface LazyImageProps {
  src: string;
  alt: string;
  className?: string;
  placeholder?: string;
  rootMargin?: string;
  threshold?: number;
}

πŸ“ Files to Modify
 Create: src/components/LazyImage/LazyImage.tsx
 Create: src/components/LazyImage/LazyImage.test.tsx
 Modify: src/components/Media/ImageCard.tsx
 Modify: src/components/Media/ChronologicalGallery.tsx
 Modify: src/components/Media/MediaThumbnails.tsx
 Optional: Create src/hooks/useIntersectionObserver.ts

βœ… Acceptance Criteria
 Images only load when they are about to enter the viewport
 Skeleton loading state displays before image loads
 Error state shows fallback image if load fails
 No performance degradation (should improve!)
 Works with existing image viewer functionality
 Maintains aspect ratio during loading
 Works in both light and dark mode
 Unit tests added for LazyImage component
 No accessibility regressions
🎨 UI/UX Requirements
Loading State:

Show skeleton with shimmer effect
Maintain image aspect ratio to prevent layout shift
Smooth fade-in transition when image loads
Error State:

Show placeholder with broken image icon
Display error message on hover
Allow retry on click
Performance:

Root margin: 200px (load images 200px before viewport)
Threshold: 0.1 (trigger when 10% visible)
Debounce scroll events if needed
πŸ”— Related Issues
Related to performance optimization
May help with #935 (responsive issues)
Could improve mobile experience
πŸ“š Resources
[MDN - Intersection Observer API](vscode-file://vscode-app/c:/Users/miet/AppData/Local/Programs/Microsoft%20VS%20Code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)
[React Lazy Load Images](vscode-file://vscode-app/c:/Users/miet/AppData/Local/Programs/Microsoft%20VS%20Code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)
[Web.dev - Lazy Loading Images](vscode-file://vscode-app/c:/Users/miet/AppData/Local/Programs/Microsoft%20VS%20Code/resources/app/out/vs/code/electron-browser/workbench/workbench.html)
πŸ–ΌοΈ Example Code
πŸ§ͺ Testing Strategy
Unit Tests:

Component renders correctly
IntersectionObserver is called
Loading states work as expected
Error handling works
Integration Tests:

Works with image gallery
Scroll behavior triggers loading
Multiple images load correctly
Manual Testing:

Test with 1000+ images
Test on slow network (throttle to 3G)
Test with images that fail to load
Check for layout shifts
πŸ’­ Additional Notes
Benefits:
πŸš€ Faster initial page load
πŸ’Ύ Reduced memory usage
πŸ“‰ Lower bandwidth consumption
⚑ Better perceived performance
πŸ“± Improved mobile experience

Considerations:
Should work with existing image caching
Must not break image viewer functionality
Should respect user's reduced motion preferences
Consider adding blur-up effect for better UX
πŸ“ Record
 I agree to follow this project's Code of Conduct
 I want to work on this issue



### Record

- [x] I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions