Optimize avatar pictures #4307

Closed
opened 2025-11-02 05:45:25 -06:00 by GiteaMirror · 13 comments
Owner

Originally created by @guillep2k on GitHub (Nov 13, 2019).

  • Gitea version (or commit ref): pre-1.11 (7b75603ffe)

Description

Currently there are few restrictions for the avatars the users can upload. Since the admin has no control on what avatars are uploaded, some effort should be done to reduce their size in bytes on Gitea. I don't mean to limit the file size but to reduce the image size on the server.

Avatars are one of the reasons a page may take a long time for first-load. Currently I've got a 390KB avatar at one test repo, and I'm sure I could upload something heavier.

Originally created by @guillep2k on GitHub (Nov 13, 2019). - Gitea version (or commit ref): pre-1.11 (7b75603ffed7e1bcdde7819e35d86d54d3bfc0ae) ## Description Currently there are few restrictions for the avatars the users can upload. Since the admin has no control on what avatars are uploaded, some effort should be done to reduce their size in bytes on Gitea. I don't mean to limit the file size but to reduce the image size on the server. Avatars are one of the reasons a page may take a long time for first-load. Currently I've got a 390KB avatar at one test repo, and I'm sure I could upload something heavier.
GiteaMirror added the performance/speedissue/confirmedtype/enhancement labels 2025-11-02 05:45:25 -06:00
Author
Owner

@silverwind commented on GitHub (Nov 13, 2019):

Image size could be reduced to a factor of 2-4 of the maximum displayed avatar size. Afterwards tools like pngcrush or zopflipng (and equivalents for other formats) could be applied to optimize for size.

@silverwind commented on GitHub (Nov 13, 2019): Image size could be reduced to a factor of 2-4 of the maximum displayed avatar size. Afterwards tools like `pngcrush` or `zopflipng` (and equivalents for other formats) could be applied to optimize for size.
Author
Owner

@tylerchambers commented on GitHub (Nov 24, 2019):

This could be done in the prepare function in the avatar package.

It looks like the prepare function seems to do what we want (mostly). But we could modify it a bit to down size the image before storing it. For additional compression without any external dependencies like pngcrush or zopflipng we could change encoding to a jpeg and decrease the quality using image/jpeg.Encode (but jpg is gross).

Interested in working on this, just need more info on how ya'll would like to proceed.

@tylerchambers commented on GitHub (Nov 24, 2019): This could be done in the prepare function in the avatar package. It looks like the prepare function seems to do what we want (mostly). But we could modify it a bit to down size the image before storing it. For additional compression without any external dependencies like pngcrush or zopflipng we could change encoding to a jpeg and decrease the quality using image/jpeg.Encode (but jpg is gross). Interested in working on this, just need more info on how ya'll would like to proceed.
Author
Owner

@guillep2k commented on GitHub (Nov 24, 2019):

@tylerchambers That would be cool!

I'm not familiar with jpeg compression techniques, but can it be targeted to a certain file size? (rather than a percentage). A possibility is to define a maximum size (in bytes), and any picture bigger than that can be recompressed in 5~10% steps until getting below the target value. The site admin could configure the size in app.ini. That should maintain a reasonable amount of quality, and users could upload the picture in any supported format. The format will be honored if the file size is within limits.

@guillep2k commented on GitHub (Nov 24, 2019): @tylerchambers That would be cool! I'm not familiar with jpeg compression techniques, but can it be targeted to a certain file size? (rather than a percentage). A possibility is to define a maximum size (in bytes), and any picture bigger than that can be recompressed in 5~10% steps until getting below the target value. The site admin could configure the size in `app.ini`. That should maintain a reasonable amount of quality, and users could upload the picture in any supported format. The format will be honored if the file size is within limits.
Author
Owner

@lunny commented on GitHub (Nov 25, 2019):

I think we may store orignal images and thumbnail images.

@lunny commented on GitHub (Nov 25, 2019): I think we may store orignal images and thumbnail images.
Author
Owner

@guillep2k commented on GitHub (Nov 25, 2019):

I think we may store orignal images and thumbnail images.

Oh, true! For the profile page picture. Makes sense.

@guillep2k commented on GitHub (Nov 25, 2019): > > > I think we may store orignal images and thumbnail images. Oh, true! For the profile page picture. Makes sense.
Author
Owner

@stale[bot] commented on GitHub (Jan 24, 2020):

This issue has been automatically marked as stale because it has not had recent activity. I am here to help clear issues left open even if solved or waiting for more insight. This issue will be closed if no further activity occurs during the next 2 weeks. If the issue is still valid just add a comment to keep it alive. Thank you for your contributions.

@stale[bot] commented on GitHub (Jan 24, 2020): This issue has been automatically marked as stale because it has not had recent activity. I am here to help clear issues left open even if solved or waiting for more insight. This issue will be closed if no further activity occurs during the next 2 weeks. If the issue is still valid just add a comment to keep it alive. Thank you for your contributions.
Author
Owner

@guillep2k commented on GitHub (Feb 4, 2020):

Does this lib look attractive? https://github.com/disintegration/imaging

https://github.com/nfnt/resize is no longer maintained

https://github.com/gographics/imagick seems heavy

@guillep2k commented on GitHub (Feb 4, 2020): Does this lib look attractive? https://github.com/disintegration/imaging https://github.com/nfnt/resize is no longer maintained https://github.com/gographics/imagick seems heavy
Author
Owner

@lunny commented on GitHub (Feb 4, 2020):

@guillep2k Looks good.

@lunny commented on GitHub (Feb 4, 2020): @guillep2k Looks good.
Author
Owner

@silverwind commented on GitHub (Feb 5, 2020):

@guillep2k doesn't look it can do lossless size optimization, but it's a start for resizing.

@silverwind commented on GitHub (Feb 5, 2020): @guillep2k doesn't look it can do lossless size optimization, but it's a start for resizing.
Author
Owner

@zpuskas commented on GitHub (May 10, 2023):

Gitea actually inflates avatar image sizes. Uploading a 256x256 pixel PNG image with a 41.8kB size, turns into 392.84kB after it's upscaled to 290x290 pixels by Gitea. Then this inflated image is used everywhere, even when the display size is 28x28px.

In fact for example on the diff view the same ~400kB image is loaded twice, with different ?size= parameters, once for the top right user menu and once when displaying the author of the diff.

So in effect instead of using the original 41.8kB image everywhere with browser scaling, we now download 785.68kB of data to display the same thing. That's increasing data transfer for the image 18x to achieve the same result!

This also means an overall 50% increase in traffic to display the page without compression: ~0.8MB for index.css, ~1MB for index.js, and another ~100kB for other files, ~800kB for the avatar image. If compression for content is enabled, which reduces CSS and JS size significantly, then the inflated avatar image downloads represent half of the page's 1.37MB traffic!

@zpuskas commented on GitHub (May 10, 2023): Gitea actually inflates avatar image sizes. Uploading a 256x256 pixel PNG image with a 41.8kB size, turns into 392.84kB after it's upscaled to 290x290 pixels by Gitea. Then this inflated image is used everywhere, even when the display size is 28x28px. In fact for example on the diff view the same ~400kB image is loaded twice, with different `?size=` parameters, once for the top right user menu and once when displaying the author of the diff. So in effect instead of using the original 41.8kB image everywhere with browser scaling, we now download 785.68kB of data to display the same thing. That's increasing data transfer for the image 18x to achieve the same result! This also means an overall 50% increase in traffic to display the page without compression: ~0.8MB for index.css, ~1MB for index.js, and another ~100kB for other files, ~800kB for the avatar image. If compression for content is enabled, which reduces CSS and JS size significantly, then the inflated avatar image downloads represent half of the page's 1.37MB traffic!
Author
Owner

@silverwind commented on GitHub (May 10, 2023):

Sounds this is definitely improvable. https://github.com/go-gitea/gitea/issues/24263 is also related here.

@silverwind commented on GitHub (May 10, 2023): Sounds this is definitely improvable. https://github.com/go-gitea/gitea/issues/24263 is also related here.
Author
Owner

@wxiaoguang commented on GitHub (May 10, 2023):

There must be something wrong.

A quick approach (patch) could be: if the newly compressed image is larger than before, then use the old (small) one.

@wxiaoguang commented on GitHub (May 10, 2023): There must be something wrong. A quick approach (patch) could be: if the newly compressed image is larger than before, then use the old (small) one.
Author
Owner

@wxiaoguang commented on GitHub (May 11, 2023):

-> Improve avatar uploading / resizing / compresing #24653

@wxiaoguang commented on GitHub (May 11, 2023): -> Improve avatar uploading / resizing / compresing #24653
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/gitea#4307