Skip to content

Optimize avatar pictures #8972

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

Closed
guillep2k opened this issue Nov 13, 2019 · 13 comments · Fixed by #24653
Closed

Optimize avatar pictures #8972

guillep2k opened this issue Nov 13, 2019 · 13 comments · Fixed by #24653
Labels
issue/confirmed Issue has been reviewed and confirmed to be present or accepted to be implemented performance/speed performance issues with slow downs type/enhancement An improvement of existing functionality

Comments

@guillep2k
Copy link
Member

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

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.

@silverwind
Copy link
Member

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.

@lunny lunny added the type/enhancement An improvement of existing functionality label Nov 14, 2019
@tylerchambers
Copy link

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.

@guillep2k
Copy link
Member Author

@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.

@lunny
Copy link
Member

lunny commented Nov 25, 2019

I think we may store orignal images and thumbnail images.

@guillep2k
Copy link
Member Author

I think we may store orignal images and thumbnail images.

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

@stale
Copy link

stale bot commented 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 stale bot added the issue/stale label Jan 24, 2020
@lunny lunny added the issue/confirmed Issue has been reviewed and confirmed to be present or accepted to be implemented label Jan 24, 2020
@stale stale bot removed the issue/stale label Jan 24, 2020
@guillep2k
Copy link
Member Author

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

@lunny
Copy link
Member

lunny commented Feb 4, 2020

@guillep2k Looks good.

@silverwind
Copy link
Member

silverwind commented Feb 5, 2020

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

@zpuskas
Copy link

zpuskas commented 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!

@silverwind
Copy link
Member

Sounds this is definitely improvable. #24263 is also related here.

@silverwind silverwind added the performance/speed performance issues with slow downs label May 10, 2023
@wxiaoguang
Copy link
Contributor

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
Copy link
Contributor

-> Improve avatar uploading / resizing / compresing #24653

silverwind added a commit that referenced this issue May 13, 2023
…rd module (#24653)

Fixes: #8972
Fixes: #24263

And I think it also (partially) fix #24263 (no need to convert) ,
because users could upload any supported image format if it isn't larger
than AVATAR_MAX_ORIGIN_SIZE


The main idea: 

* if the uploaded file size is not larger than AVATAR_MAX_ORIGIN_SIZE,
use the origin
* if the resized size is larger than the origin, use the origin

Screenshots:

JPG:

<details>


![image](https://github.com/go-gitea/gitea/assets/2114189/70e98bb0-ecb9-4c4e-a89f-4a37d4e37f8e)

</details>

APNG:

<details>


![image](https://github.com/go-gitea/gitea/assets/2114189/9055135b-5e2d-4152-bd72-596fcb7c6671)


![image](https://github.com/go-gitea/gitea/assets/2114189/50364caf-f7f6-4241-a289-e485fe4cd582)

</details>

WebP (animated)

<details>


![image](https://github.com/go-gitea/gitea/assets/2114189/f642eb85-498a-49a5-86bf-0a7b04089ae0)

</details>

The only exception: if a WebP image is larger than MaxOriginSize and it
is animated, then current `webp` package can't decode it, so only in
this case it isn't supported. IMO no need to support such case: why a
user would upload a 1MB animated webp as avatar? crazy .....

---------

Co-authored-by: silverwind <[email protected]>
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
issue/confirmed Issue has been reviewed and confirmed to be present or accepted to be implemented performance/speed performance issues with slow downs type/enhancement An improvement of existing functionality
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants