Skip to content

Conversation

EinToni
Copy link
Contributor

@EinToni EinToni commented Apr 17, 2025

Description

  • Creating the small thumbnails takes quite some time, which should not be underestimated.
  • The time needed to generate the small or big thumbnail is not too different from each other. Therefore there is no real benefit of the small thumbnail and it only adds frustration to the end user experience. That is because the image appeared to have loaded (the visual move from blur to something better) but it's still so bad that it is basically a blur. The better solution is therefore to stay at the blur until the actual thumbnail has loaded.
  • Additionaly to the faster generation of the thumbnail, it now also gets cached similarly to the remote thumbnail which already gets cached. This further speeds up the all over usage of the app and prevents a repeatet thumbnail generation when opening the app.

Fixes #13105

How Has This Been Tested?

  1. No more small thumbnails
  • When scrolling around viewing local images (e.g. in the "on this device" tab), the images previously loaded as: placeholder -> blur -> small thumbnail -> actual thumbnail
  • Now the images load as: placeholder -> blur -> actual thumbnail
  1. Cached local thumbnails
  • After viewing the local images close the app and reopen
  • All local images that were previously viewed load in an instant as they are cached.

Videos

Before the change. Including the small thumbnail and a noticeable delay before the actual thumbnail gets loaded:
https://github.com/user-attachments/assets/ddc6f6a2-17f3-4b9d-8014-7ea7f199d097

After the change. No more small thumbnail, the actual thumbnail gets loaded directly, without delay and faster:
https://github.com/user-attachments/assets/3bfa4418-38f0-4677-a77d-8833cf707d3c

Checklist:

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation if applicable
  • I have no unrelated changes in the PR.
  • I have confirmed that any new dependencies are strictly necessary.
  • I have written tests for new code (if applicable)
  • I have followed naming conventions/patterns in the surrounding code
  • All code in src/services/ uses repositories implementations for database calls, filesystem operations, etc.
  • All code in src/repositories/ is pretty basic/simple and does not have any immich specific logic (that belongs in src/services/)

* Creating the small thumbnails takes quite some time, which should not be underestimated.
* The time needed to generate the small or big thumbnail is not too different from each other. Therefore there is no real benefit of the small thumbnail and it only adds frustration to the end user experience. That is because the image appeared to have loaded (the visual move from blur to something better) but it's still so bad that it is basically a blur. The better solution is therefore to stay at the blur until the actual thumbnail has loaded.
* Additionaly to the faster generation of the thumbnail, it now also gets cached similarly to the remote thumbnail which already gets cached. This further speeds up the all over usage of the app and prevents a repeatet thumbnail generation when opening the app.
* Decreased the quality from the default 95 to 80 to provide similar quality with much reduces thumbnail size.
* Use try catch around the read of the cache file.
@shenlong-tanwen shenlong-tanwen changed the title Remove small thumbnail and cache generated thumbnails perf(mobile): remove small thumbnail and cache generated thumbnails Apr 18, 2025
@EinToni
Copy link
Contributor Author

EinToni commented Apr 18, 2025

@shenlong-tanwen @mertalev Another thing that came to mind is the cache key. Maybe it would be best to use the checksum as the cache key, this way also duplicate images (possible in local folders) could also benefit from the cached image without extra recalculation. I know this would probably be a quite rare case, but could nevertheless be useful.
What are your thoughts about that?

Copy link
Member

@mertalev mertalev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good aside from that nit

yield codec;
return;
} catch (error) {
debugPrint("Loading of thumbnail failed: ${error.toString()}");
Copy link
Member

@mertalev mertalev Apr 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debugPrint should be wrapped with kDebugMode

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see. But failing to load the cached thumbnail is quite severe and if that happens more often (for what ever reason) it could impact the ux. Shouldn't this be therefore logged always as a e.g. severe log?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't it just mean the thumbnail is regenerated instead (which is the current behavior always anyway)? I think it can happen if e.g. someone clears the app cache, at which point they'll probably get thousands of these logs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, if they clear the cache, the fileFromCache will be null and it will be directly switched to generating the thumbnail.
If the catch gets invoked, something got loaded from cache (fileFromCache != null) but providing it failed for some reason (maybe fileFromCache.file.path is null)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, so clearing the app cache doesn't just delete the files, but deletes the cache entries too? I see. In that case it probably warrants a log.severe message since the catch shouldn't be reached in normal circumstances.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. I replaced the debugPrint with a log.severe .

@EinToni
Copy link
Contributor Author

EinToni commented Apr 18, 2025

Awesome, thank you @mertalev
Do you have an opinion regarding the cache key I posted above?

@mertalev
Copy link
Member

Awesome, thank you @mertalev Do you have an opinion regarding the cache key I posted above?

I'm not sure about it. Checksumming can take a long time in some cases (especially when iCloud is involved), so it could be useful to have a "local-only" page somewhere in the app that doesn't rely on checksums so the app is usable in the meantime. Baking checksums into the thumbnail loader itself would make that impossible.

@EinToni
Copy link
Contributor Author

EinToni commented Apr 18, 2025

Okay then it is probably best to leave the cache key like it is.

@EinToni
Copy link
Contributor Author

EinToni commented Apr 21, 2025

@mertalev Can I provide anything more for this to get merged soon so the changes make it into the next release?

@alextran1502
Copy link
Member

@EinToni i will run some test today and merge it in

@alextran1502 alextran1502 merged commit b71039e into immich-app:main Apr 21, 2025
39 checks passed
alextran1502 added a commit that referenced this pull request Apr 22, 2025
alextran1502 added a commit that referenced this pull request Apr 22, 2025
* Revert "fix(mobile): use immutable cache keys for local images (#17736)"

This reverts commit 010b144.

* Revert "perf(mobile): remove small thumbnail and cache generated thumbnails (#17682)"

This reverts commit b71039e.
shenlong-tanwen pushed a commit that referenced this pull request Jun 8, 2025
…17682)

* Remove small thumbnail and cache generated thumbnails

* Creating the small thumbnails takes quite some time, which should not be underestimated.
* The time needed to generate the small or big thumbnail is not too different from each other. Therefore there is no real benefit of the small thumbnail and it only adds frustration to the end user experience. That is because the image appeared to have loaded (the visual move from blur to something better) but it's still so bad that it is basically a blur. The better solution is therefore to stay at the blur until the actual thumbnail has loaded.
* Additionaly to the faster generation of the thumbnail, it now also gets cached similarly to the remote thumbnail which already gets cached. This further speeds up the all over usage of the app and prevents a repeatet thumbnail generation when opening the app.

* Decrease quality and use try catch

* Decreased the quality from the default 95 to 80 to provide similar quality with much reduces thumbnail size.
* Use try catch around the read of the cache file.

* Replace ImmutableBuffer.fromUint8List with ImmutableBuffer.fromFilePath

* Removed unnecessary comment

* Replace debugPrint with log.severe for catch of error

---------

Co-authored-by: Alex <[email protected]>
shenlong-tanwen pushed a commit that referenced this pull request Jun 8, 2025
* Revert "fix(mobile): use immutable cache keys for local images (#17736)"

This reverts commit 010b144.

* Revert "perf(mobile): remove small thumbnail and cache generated thumbnails (#17682)"

This reverts commit b71039e.
savely-krasovsky pushed a commit to savely-krasovsky/immich that referenced this pull request Jun 8, 2025
…mmich-app#17682)

* Remove small thumbnail and cache generated thumbnails

* Creating the small thumbnails takes quite some time, which should not be underestimated.
* The time needed to generate the small or big thumbnail is not too different from each other. Therefore there is no real benefit of the small thumbnail and it only adds frustration to the end user experience. That is because the image appeared to have loaded (the visual move from blur to something better) but it's still so bad that it is basically a blur. The better solution is therefore to stay at the blur until the actual thumbnail has loaded.
* Additionaly to the faster generation of the thumbnail, it now also gets cached similarly to the remote thumbnail which already gets cached. This further speeds up the all over usage of the app and prevents a repeatet thumbnail generation when opening the app.

* Decrease quality and use try catch

* Decreased the quality from the default 95 to 80 to provide similar quality with much reduces thumbnail size.
* Use try catch around the read of the cache file.

* Replace ImmutableBuffer.fromUint8List with ImmutableBuffer.fromFilePath

* Removed unnecessary comment

* Replace debugPrint with log.severe for catch of error

---------

Co-authored-by: Alex <[email protected]>
savely-krasovsky pushed a commit to savely-krasovsky/immich that referenced this pull request Jun 8, 2025
* Revert "fix(mobile): use immutable cache keys for local images (immich-app#17736)"

This reverts commit 010b144.

* Revert "perf(mobile): remove small thumbnail and cache generated thumbnails (immich-app#17682)"

This reverts commit b71039e.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

mobile: thumbnails load feels slow, possibly due to extra thumbnail generation step
4 participants