Skip to content

perf(mobile): remove small thumbnail and cache generated thumbnails #17792

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 23, 2025

Conversation

EinToni
Copy link
Contributor

@EinToni EinToni commented Apr 22, 2025

Description

Redo of #17682 after it got reverted in #17786

It contains the same implementation with two adaptions, the key now uses the ownerId of the asset (is there maybe a better way to get the userId or is this the preferred way) and secondly I replaced the usage of the asset in the _codec method with the key provided as parameter, as suggested by @shenlong-tanwen in #17787

Instead of the user id, the checksum of the file would probably also work.

The changes:

  • 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.
  • Use the key provided in the loadImage method instead of the asset of the constructor.

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/)

@alextran1502
Copy link
Contributor

alextran1502 commented Apr 22, 2025

Tested and unfortunately, the issue is still there. I don't find the custom cache implementation needed because they are already cached in this provider

I believe the ownerId is only populated when the asset is a remote one. So using it in the local asset's context will yield null

@alextran1502 alextran1502 changed the title Remove small thumbnail and cache generated thumbnails perf(mobile): remove small thumbnail and cache generated thumbnails Apr 23, 2025
@alextran1502
Copy link
Contributor

Hey, I just tested again with the checksum in the cache key construction

final cacheKey = '${key.checksum}-${key.id}-${width}x$height';

The issue with loading the wrong content is fixed. However, a problem remains on the Backup Page > Album selection > Clicking on the image icon to view the assets still renders the whole page with a single asset.

It was fixed in #17799, however, with the cache implementation in this PR, the issue pops back up.

@mertalev
Copy link
Contributor

mertalev commented Apr 23, 2025

Is there any case where checksum can be null? Maybe it should be asset id + checksum?

Hmmm, I see you already have both. I'd be interested to know what the actual key is when the backup page is open. Clearly there's a collision, but can both checksum and id be null or an empty string? No, right?

@EinToni
Copy link
Contributor Author

EinToni commented Apr 23, 2025

Oh I'm sorry... That's my mistake. I guess we should use the actual user id instead of the remote owner, something like final userId = ref.watch(currentUserProvider)?.id.
I'm currently at work, but can test it once I'm home.

@shenlong-tanwen
Copy link
Member

We also need to ensure that editing an asset that could change the thumbnail should be updated within the app as well. i.e, Let's say a local asset is flipped on device, it should be reflected in the app. This is currently an issue that needs to be addressed in the remote provider as well. Eg, Go to web, upload an asset, let it sync to the mobile app, flip the asset and use the "Replace with Upload" feature in the web to replace it with the flipped version. The app would still be displaying the older thumbnail.

We could look into using the modified time of the asset in the cache key which would fix this issue as well.

@EinToni
Copy link
Contributor Author

EinToni commented Apr 23, 2025

There are apparently quite a few factors that can affect the image. Is the checksum calculated for local images as well or only for uploaded images? If also for local images the best key would probably be:
userId-checksum-key.id-width-height
When the asset changes, the checksum should also change, therefore the modified time could be omitted, or am I missing something?

@EinToni EinToni force-pushed the localThumbnailCaching branch from 8343df9 to 0ee8a1a Compare April 23, 2025 14:13
@EinToni
Copy link
Contributor Author

EinToni commented Apr 23, 2025

I also just saw that the asset contains an id and a localId, I assume we should rather use the localId, but what exactly is the difference?

EinToni added 4 commits April 23, 2025 16:59
* 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.
* Use the key provided in the loadImage method instead of the asset of the constructor.
@EinToni EinToni force-pushed the localThumbnailCaching branch from c88ce0a to 1ac6a5e Compare April 23, 2025 15:00
Copy link
Contributor

@alextran1502 alextran1502 left a comment

Choose a reason for hiding this comment

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

All issues have been resolved! Thank you

@alextran1502 alextran1502 merged commit 59fa8fb into immich-app:main Apr 23, 2025
40 checks passed
shenlong-tanwen pushed a commit that referenced this pull request Jun 8, 2025
…17792)

* 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.
* 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.
* Use the key provided in the loadImage method instead of the asset of the constructor.

* Use userId instead of ownerId

* Remove import

* Add checksum to thumbnail cache key
savely-krasovsky pushed a commit to savely-krasovsky/immich that referenced this pull request Jun 8, 2025
…mmich-app#17792)

* 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.
* 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.
* Use the key provided in the loadImage method instead of the asset of the constructor.

* Use userId instead of ownerId

* Remove import

* Add checksum to thumbnail cache key
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.

4 participants