Optimizations
Note
Synced from tie-gui/docs/OPTIMIZATIONS.md on 2026-11-12. Edit the source, not this copy.
This document describes the memory and performance optimizations implemented to make the gallery more fluid and memory-efficient, especially on lower-end mobile devices.
Summary of Changes
1. LRU Tile Cache (gallery/tilecache.go)
- Problem: Unbounded thumbnail cache kept all loaded tiles in memory forever
- Solution: Implemented insertion-order LRU cache adapted from tie-filehost
- Impact:
- Desktop: Max 500 tiles cached (~60-120 MB depending on tile size)
- Mobile: Max 150 tiles cached (~18-36 MB)
- Old thumbnails automatically evicted when cache fills up
2. Off-screen culling via Fyne’s clip (gallery/tilelayout.go, gallery/gallery.go)
- Note: An earlier “virtual scrolling” attempt (Hide/Show off-screen tiles +
viewer.scroll.OnScrolled→gallery.Refresh()) was removed — it made scrolling choppy because*fyne.Container.Refresh()re-uploads every tile texture and fired on every scroll frame. - Current approach:
TileLayout.Layoutpositions every tile; off-screen tiles are culled by Fyne’s GL painter, which skips any object outside the scroll container’s clip rect (internal/painter/gl/painter.go). No per-scroll work is needed. - Implementation:
PlaceTilesadds all tiles atomically in a singlefyne.Do()block to prevent a race where refresh happens before tiles are added.
- Impact:
- Off-screen tiles cost no render time (painter clip test), with no per-frame relayout or refresh — smooth scrolling.
3. Improved Pagination UI
- Problem: Bottom bar pagination controls are small and difficult to tap on mobile
- Solution: Added large “Load Next Page ▼” button at end of gallery grid
- Impact:
- Button is 60px tall on desktop, 80px on mobile
- Full-width, high-importance styling for easy tapping
- Positioned after all tiles in the layout
- Only shown when more pages exist
4. Full Image Cleanup
- Problem: Full-size decoded images not released when returning to gallery
- Solution: Release
fyneImage.Imagewhen showing gallery view - Impact:
- Immediately frees 10-50 MB per full-size image
- Critical on mobile where memory is constrained
5. Mobile-Specific Config Adjustments (gallery/config.go)
- Problem: Desktop defaults too memory-intensive for mobile
- Solution:
AdjustForMobile()function reduces resource usage:- TileWidth: 300 → 200 (smaller thumbnails)
- ImagesPerPage: 500 → 100 (fewer items per page)
- Workers: 8 → 4 (less concurrent loading)
- TileGap: 5 → 3 (more compact layout)
- Impact:
- ~60% reduction in memory per page
- Still maintains good image quality (QHD screens handled well)
- Can be overridden in user config.toml if needed
6. Thumbnail Quality Considerations
- Desktop: TileWidth * 2 (600px wide thumbnails)
- Mobile: TileWidth * 2 (400px wide after adjustment)
- Both scales maintain high quality for 2× display scaling (Retina, QHD, etc.)
- JPEG quality: 90 for images, 85 for directory composites
Performance Characteristics
Before Optimizations
- Loading 500 images: All created as placeholders immediately
- Memory usage: ~200-300 MB for gallery (500 tiles + full images)
- Scroll performance: All tiles rendered, even off-screen
- Mobile: Laggy loading, high memory pressure
After Optimizations
- Loading 100 images (mobile): Progressive loading with virtual scrolling
- Memory usage: ~50-80 MB for gallery (visible tiles only + LRU cache)
- Scroll performance: Smooth, only renders visible area
- Mobile: Fluid experience even on lower-end devices
Future Optimization Opportunities
Progressive/Chunked Loading: Currently all page tiles are created at once. Could load first 2-3 rows immediately, then load more as user scrolls.
Thumbnail Resolution Scaling: Could detect actual screen DPI and adjust thumbnail generation resolution (1×, 1.5×, 2×) instead of always using 2×.
Disk Cache Cleanup: LRU eviction only happens in-memory. Disk cache in
~/.cache/imgviewgrows unbounded. Could implement periodic cleanup or size limits.Gesture-Triggered Prefetch: On mobile, could prefetch next page when user scrolls past 80% of current page.
Memory Pressure Handling: Could listen for OS memory warnings and proactively shrink cache size.
UI Features
Filename Label Toggle
Default State: Labels are OFF by default to maximize vertical space (saves ~22px per row).
How to toggle:
- Desktop: Press N key (configurable in config.toml as
ToggleFilenames) OR click ☰ menu → “Show/Hide filenames” - Mobile: Tap ☰ menu (bottom-right) → “Show/Hide filenames”
The ☰ menu button appears in the bottom-right corner of the gallery on both mobile and desktop. It provides a discoverable, standard way to access settings without needing keyboard shortcuts or hidden gestures.
When labels are hidden:
- Labels are not rendered (
Hide()called on label widgets) - Tile height excludes label space (extraH = 0)
- Layout automatically recalculates to use full tile height for images
- No white space left where labels would be
When labels are shown:
- Displays basename only (e.g., “IMG_1234.jpg” not full path)
- One text line’s height (theme text size + inner padding; 27px with the default theme) is reserved below each thumbnail, so a zoomed/larger font cannot draw over the next row’s thumbnail
- Center-aligned with ellipsis truncation for long names
This is useful when browsing by visual recognition rather than needing filenames.
Testing
To verify the optimizations:
Desktop: Load a directory with 5000+ images, scroll through gallery
- Memory should stay under 200 MB
- Scrolling should be smooth (both down and back up)
- Tiles should reappear correctly when scrolling back up (no white space)
- Pagination button should appear at end of each page
- Press ‘N’ to toggle filenames - no white space should remain when hidden
Mobile: Load 100+ images on low-end device (2GB RAM)
- Initial load should be fast (not waiting for all tiles)
- Scrolling should be fluid
- Memory usage should stay reasonable (no OOM crashes)
- “Next Page” button should be easily tappable
Cache Behavior: Load page 1, scroll to page 2, return to page 1
- Tiles should reload from cache (instant)
- After scrolling through many pages, old tiles should be evicted
Configuration
Users can override mobile defaults in ~/.config/imgview/config.toml:
[General]
TileWidth = 250 # Override default mobile 200
ImagesPerPage = 200 # Override default mobile 100
Workers = 6 # Override default mobile 4
TileGap = 4 # Override default mobile 3The automatic mobile detection can’t be disabled, but these values take precedence.