Skip to content
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

Enhancing slow photo loading #3626

Closed
mselley opened this issue Jul 21, 2020 · 17 comments
Closed

Enhancing slow photo loading #3626

mselley opened this issue Jul 21, 2020 · 17 comments

Comments

@mselley
Copy link

mselley commented Jul 21, 2020

​For reference the CPU used in this test was an i5 2400 and the images were all JPG and range between 3mb and 6mb all shot from the same camera at 4608x3456.

First part is looking at the thumbnail generation as it is taking quite a long time, with initial load of the thumbnails of a particular resolution are taking between 1-5 second to generate. First clear issue here is with portrait images which are taking 5 times longer to render than landscape ones, these are all taking 4+ seconds. Looks like the way these are generated could do with some enhancement.

The second and main part is the thumbnail/image caching on the server.

After the first load of the thumbnails the server is caching these and i am getting 1-3 ms responses. Shown below.

2019-07-26 07:20:50.800 Info HttpServer: HTTP Response 200 to 192.168.1.61. Time: 1ms. http://192.168.1.200:8096/emby/Items/2842/Images/Primary?maxHeight=212&maxWidth=282&tag=6157ab6c2e11e6a46782b585946f8f94&quality=90

This theory is fine until we dig a little deeper to see how these are being handled. I noticed the thumbnails are generated by exact resolution. So if the browser size is changed by a couple of pixels which causes the thumbnails on the page to change size by a few pixels then the server will go away and regenerate all of these again taking 1-5 seconds an image. This means switching between devices or moving your browser around will set you back to an unusable state.

I have put some examples below to show what currently happens, as you can see the request at 2019-07-26 07:19:44.520 is only 1 pixel different to the previous one taking another 4 second to render.

2019-07-26 07:13:00.124 Info HttpServer: HTTP Response 200 to 192.168.1.61. Time: 4542ms. http://192.168.1.200:8096/emby/Items/2777/Images/Primary?maxHeight=209&maxWidth=278&tag=552c5873880a860874a1ae556fb5a22a&quality=90

2019-07-26 07:16:08.560 Info HttpServer: HTTP Response 200 to 192.168.1.61. Time: 1ms. http://192.168.1.200:8096/emby/Items/2777/Images/Primary?maxHeight=217&maxWidth=289&tag=552c5873880a860874a1ae556fb5a22a&quality=90

2019-07-26 07:16:56.573 Info HttpServer: HTTP Response 200 to 192.168.1.61. Time: 1ms. http://192.168.1.200:8096/emby/Items/2777/Images/Primary?maxHeight=217&maxWidth=289&tag=552c5873880a860874a1ae556fb5a22a&quality=90

2019-07-26 07:17:29.933 Info HttpServer: HTTP Response 200 to 192.168.1.61. Time: 4926ms. http://192.168.1.200:8096/emby/Items/2777/Images/Primary?maxHeight=212&maxWidth=283&tag=552c5873880a860874a1ae556fb5a22a&quality=90

2019-07-26 07:18:15.684 Info HttpServer: HTTP Response 200 to 192.168.1.61. Time: 2ms. http://192.168.1.200:8096/emby/Items/2777/Images/Primary?maxHeight=212&maxWidth=283&tag=552c5873880a860874a1ae556fb5a22a&quality=90

2019-07-26 07:18:38.563 Info HttpServer: HTTP Response 200 to 192.168.1.61. Time: 1ms. http://192.168.1.200:8096/emby/Items/2777/Images/Primary?maxHeight=212&maxWidth=283&tag=552c5873880a860874a1ae556fb5a22a&quality=90

2019-07-26 07:19:44.520 Info HttpServer: HTTP Response 200 to 192.168.1.61. Time: 4428ms. http://192.168.1.200:8096/emby/Items/2777/Images/Primary?maxHeight=212&maxWidth=282&tag=552c5873880a860874a1ae556fb5a22a&quality=90

2019-07-26 07:20:49.970 Info HttpServer: HTTP Response 200 to 192.168.1.61. Time: 2ms. http://192.168.1.200:8096/emby/Items/2777/Images/Primary?maxHeight=212&maxWidth=282&tag=552c5873880a860874a1ae556fb5a22a&quality=90

The main issue with the caching on the sizes being this exact is that it ends up being device specific, which kind of defeats the purpose of the server side cache. Even devices with the same screen resolution but another user having an extra toolbar in the browser will cause the size difference.

The other issue is the cache that is used for these thumbnails is only valid for 30 days. This means as with photo albums that i may not look at again for a few months so i will have to wait all over again.

I would suggest that it makes sense to work on a range basis, as the transfer size is negligible between a few pixels and then the image resizing to the exact thumbnail size is offloaded to the client which again is minimal. This could be something like Large Medium Small. Any client side request for thumbnails within the size range of one of those three will get served up.

This also means that we could Pre-Cache all the thumbnails for a given library. This would have a huge performance increase for viewing photo libraries with Emby. This would be an optional setting due to the time and disk space required to perform this when a library is scanned. Disk space is cheap these days and lots of people are using 24/7 machines to run emby, so would be no issues if it took a few days to cache my whole photo library.

It its also very slow to view the full size images especially portrait ones, so i can only assume similar rendering logic is being used for the full size.

I am not sure how thumbnails are handled for Videos and Music, but this may or may not be relevant to those too.

@luisgreen
Copy link

In the meanwhile I wrote this gist that helps to cache the thumbnails inside an NGINX container and REALLY accelerate the load times.

https://gist.github.com/luisgreen/7f98f90d7d934ed8081eb802c156c7a9

Maybe @LukePulverenti and @mselley can take a look at it to alleviate his server as I did. I still have no metrics as I did just today.

Hope this helps.

@Statick
Copy link

Statick commented Feb 20, 2021

+1 for improvements on this
my issue is media being stored across a slow connection meaning that thumbnail regeneration similarly takes a couple of seconds per image, when this regeneration is completely unneccessary

@LukePulverenti
Copy link
Member

Hi there, is Emby Server 4.6 performing any better in this regard?

@Statick
Copy link

Statick commented Jun 24, 2021

it appears to be the case that thumbs cached on one device are no longer being regenerated on another device, so yeah that's a big improvement

I can't say yet whether thumbs are persisting for more than 30 days - emby is currently regenerating a whole folder's worth of these right now, which had previously been generated several months ago, but maybe after doing it this time they will persist indefinitely

@mselley
Copy link
Author

mselley commented Jun 24, 2021

Hi there, is Emby Server 4.6 performing any better in this regard?

Just having a look will come back.
Is it possible for you to say what changes were made to improve this?

@LukePulverenti
Copy link
Member

The image processing has not changed too much, but there were some cases of data not being cached and reused for future use. By data I mean properties about the image that tell us if we can serve the original directly, use an existing processed copy, etc. So what was happening in 4.5 was there were some cases where images would be repeatedly opened and analyzed only to then determine that we could serve the original directly.

@mselley
Copy link
Author

mselley commented Jun 26, 2021

Thanks luke. Yes the caching appears the cover a greater range than one pixel now by the looks of it.
Still much much slower to render a portrait image but as you said no changes have been made in that area.
How complex would it be to upfront cache multiple sizes for all the libraries as an optional setting. Disk space is cheap and with the machines on 24/7 spare cpu time is not an issue. Would mean near Instant loading for all libraries at any time.

@Statick
Copy link

Statick commented Jul 2, 2021

okay so I've just opened emby theater on the same device I was accessing emby through a browser, and every image is currently regenerating extremely slowly

would be great to avoid this by just returning the cached server files instead

@Statick
Copy link

Statick commented Jul 2, 2021

I'm guessing this is because the images used are of different sizes - my feeling here is it would be better to generate multiple cached sizes in one go, rather than reloading the source data every time a new image size is needed, based on the settings required for all devices that have previously accessed the server. obviously for new installs this would make no difference, but for newly imported data on mature installs it would save a lot of time, and ensure the client experience is always smooth and fast

@sfatula
Copy link

sfatula commented Jul 16, 2021

Same for me. 4.6.3.0, i9-9900k cpu, nvidia gpu, takes minutes to display an "album" of 29 photos, 3-6mb each, jpg. I had viewed the images using web browser on host, then viewed from ipad emby app. Both were slow. So, not cached it would appear.

@Statick
Copy link

Statick commented Jul 31, 2021

all my previously cached images have apparently "expired" and are being automatically refreshed from the source, over a slow connection, making emby basically unusable again until this is completed, which at this rate is going to take a while

there's absolutely no good reason I can think of for this to happen, the images have not changed so reloading every single one of them like this is just pointless. when this happens across a slow connection (in particular for me individual file requests are slow to open, so streaming a movie is fine but opening several hundred jpgs is very slow) then it's really frustrating. I already ran a library scan at a time that suited me, it completed in a few hours and all the images were cached. I really do not want these images to later be refreshed automatically for no reason

looking in emby's cache folder it looks like cached images are deleted after 30 days, as there's nothing more than 30 days old in there. please let us configure this behaviour ourselves, or even turn it off entirely. I don't want my cached images to ever have to be reloaded unless a library scan reveals that a file has changed. these files are tiny and not a problem, but reloading them needlessly is. internet browsers have been letting us configure our cache cleaning since the 90s!

@LukePulverenti
Copy link
Member

Regarding converting the thumbnails, we convert to webp because that produces a smaller output than jpg, however I've done some comparison and I'm seeing that on large photos, the conversion is generally 4-5X slower to convert to webp.

So I think what we'll do is establish a threshold where any image beyond a certain resolution will convert to jpg. I think we'll start with 1080p as a starting point and go from there.

@LukePulverenti
Copy link
Member

This should be improved now in Emby Server 4.7.6 and even further improved in the 4.8 beta channel.

@mselley
Copy link
Author

mselley commented Oct 3, 2022

Great thank @LukePulverenti any clues on what changes were made in 4.7.6 and what we can expect from 4.8?
Thanks

@LukePulverenti
Copy link
Member

Great thank @LukePulverenti any clues on what changes were made in 4.7.6 and what we can expect from 4.8? Thanks

On platforms where we use Skia (which is nearly all), we've changed the way we're loading images, and in some cases the improvement is dramatic.

Additionally in the 4.8 beta channel we're bringing another image processor into the mix (libvips), primarily to support more formats but we're also taking advantage of it in areas where it excels the most.

@mselley
Copy link
Author

mselley commented Oct 3, 2022

Brilliant thanks @LukePulverenti ! Great stuff I will test it out.

@LukePulverenti
Copy link
Member

We should have a lot faster image processing now in the 4.8 beta channel. If you're still having an issue please open a new topic and we'll be happy to go over it. Thanks !

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

No branches or pull requests

5 participants