go-gitea / gitea

Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD
https://gitea.com
MIT License
45.03k stars 5.49k forks source link

Support resizing of local avatars #20918

Open somera opened 2 years ago

somera commented 2 years ago

Description

When I see the size=84 parameter in the URL I think gitea should send 84x84 pixel big icon. But I see, that Gitea is sending 290x290 pixel big icon.

image

With 2000+ organizations it's need ~10 seconds, 2000+ requests and some MB's.

image

Gitea Version

1.17.1

Can you reproduce the bug on the Gitea demo site?

No

Log Gist

No response

Screenshots

No response

Git Version

2.25.1

Operating System

Ubuntu 20.04.4

How are you running Gitea?

Self hosted gitea-1.17.1-linux-amd64

Database

PostgreSQL

silverwind commented 2 years ago

Yes, seems like a bug. The intention is for the server to send 84px in this case.

somera commented 2 years ago

A can't compare this to the 1.16.x version. But in the 1.16.x release loading a page with a lot of orgas war faster. Looks like new bug in 1.17.x.

lunny commented 2 years ago

But they will be cached?

somera commented 2 years ago

But they will be cached?

Yes. But this is "strange". When I click in gitea I see "memory cached" and its fast.

image

When I try to migrate new project it slower (8-10 seconds) and I see "disk cache".

image

Tested with Chrome (Version 104.0.5112.102 (Offizieller Build) (64-Bit))

silverwind commented 2 years ago

Not sure when a browser will decide to offload to disk, but we should probably make the hardcoded 5 minute cache duration on avatars configurable:

https://github.com/go-gitea/gitea/blob/dc0253b0637bbf367ad330612900e780c6b2b0e6/routers/web/user/avatar.go#L18-L21

silverwind commented 2 years ago

https://github.com/go-gitea/gitea/pull/20958 restores avatars to use STATIC_CACHE_TIME again which defaults to 6h so we can hit the cache much more than before. Turns out it wasn't needed.

silverwind commented 2 years ago

Back to this issue's topic: The problem is that the size argument only works for external avatar services like Gravatar. The local avatar handler ignores the size argument and always serves the full-size avatar from storage.

What needs to be done:

  1. Make the /avatars/* request handler respect size and resize it.
  2. Store the resulting images in server cache and invalidate this cache when a user/org updates their avatar.

(Can someone rename issue to "Support resizing of local avatars"? I can't)

somera commented 2 years ago

@silverwind I renamed it

somera commented 2 years ago

Will be there a fix for the next (1.17.3 or 1.18.x) release?

somera commented 2 years ago

Status with 1.17.2 for the start page with 2192 organisations.

Chrome: image

FF: image

somera commented 2 years ago

I took a look on Gitea 1.16.x. This version has the same scale bug.

But I thin that with my gitea usage (generating a lot of organizations) I reached some subability and load time limitations. Just create on you local instances ~2000 orgas for see what I mean. On gitea.com are ~1140 orgas. If you log there with admin permissions than you could analyze my experience with the loading time.

  1. When I want create a new repo or mirror in specific orga, than you don't need load all orgas in the following pages.

image

This make no sense for me.

  1. Why there is an icon needed in the drop list?

  2. On the start page there is a search field for repos. But not for orgas. All orgs will be loades. image

image

This is not consistent.

  1. On the start page the drop-down list with orgas is not a good idea if you have a lot otf them. In this case the search box in 3. will be a better solution. image
somera commented 2 years ago

I have one idea to solve this problem for the avatar url calls. Just add new property:

[picture]
ENABLE_AVATAR_IN_LISTS = false -> default is 'true'

Is this set to false, than in all lists (start page/issues/pull requests/milestones, new repo/mirror) the avatar image url in the select list will be not shown. And the scale bug should be fixed to.

@silverwind I wanted add an nginx proxy with image scaling/caching. But I found that the scale size don't correspond to the rendered sice in the browser. Some examples.

image

image

image

image

image

image

image

somera commented 2 years ago

Last days I installed Nginx as proxy and added avatar scaling. This is reducing only the amount of data which is sended to the client.

I see here two problems:

somera commented 2 years ago

image

somera commented 1 year ago

I have now an nginx proxy with working scaling. Cause my gitea with 3200 avatars is "slow".

/etc/nginx/nginx.conf:

http {
    map $request_uri $width {
        default 28;
        ~\?size=512 512;
        ~\?size=420 420;
        ~\?size=280 280;
        ~\?size=140 140;
        ~\?size=100 100;
        ~\?size=84 84;
        ~\?size=72 72;
        ~\?size=56 56;
        ~\?size=48 48;
        ~\?size=45 45;
        ~\?size=40 40;
        ~\?size=28 28;
        ~\?size=24 24;
    }
}

/etc/nginx/conf.d/gitea.conf:

server {
    location ~ "^/git/avatars/(?<image>[0-9a-f]+)$" {
        # nginx user is added to the git group and
        # /usr/share/nginx/gitea_avatars_current is a soft link to /var/lib/gitea/data/avatars
        alias /usr/share/nginx/gitea_avatars_current/$image;

        proxy_cache_key "$image$width";
        proxy_cache nginx_cache;
        proxy_cache_valid any 60m;
        add_header X-Proxy-Cache $upstream_cache_status;
        add_header X-Avatar-Filename $image;
        add_header X-Avatar-Width $width;
        add_header Cache-Control "public, max-age=600";

        image_filter test;
        image_filter_jpeg_quality 75;
        image_filter resize $width -;

        access_log /var/log/nginx/gitea_avatars.access.log;
        error_log /var/log/nginx/gitea_avatars.error.log error;
    }

    # Note: Trailing slash
    location /git/ {
        client_max_body_size 364M;

        # Note: Trailing slash
        proxy_pass http://localhost:3000/;

        proxy_connect_timeout 600;
        proxy_send_timeout 600;
        proxy_read_timeout 600;

        send_timeout 600;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        access_log /var/log/nginx/gitea.access.log;
        error_log /var/log/nginx/gitea.error.log error;
    }

    location /git/_/static/assets/ {
        alias /usr/share/nginx/gitea_public/;

        proxy_cache nginx_cache;
        proxy_cache_valid any 60m;
        add_header X-Proxy-Cache $upstream_cache_status;

        access_log /var/log/nginx/gitea_public.access.log;
        error_log /var/log/nginx/gitea_public.error.log error;
    }
}

Should this stay open? For me, can this be closed.

silverwind commented 1 year ago

Keep it open, we still want to fix this and implement resizing on upload and ideally resize any existing oversized avatars.

SrAquaGenius commented 7 months ago

Hi, while trying to solve this issue, I have some questions:

I am also interested in coding avatar resizing availability as a new feature! Greetings

somera commented 3 months ago

Hi, while trying to solve this issue, I have some questions:

Who can answer this questions?

  • What is the functionality of RenderedSizeFactor, defined in picture.go and equal to 2. That can explain why some avatars/url-size are in one-to-two ratio.
  • The maximum avatar width (and height) is 4096. Isn't that unnecessarily big?

Ups ... I would say: too big!

  • Where exactly is the avatar request handler?
  • Finally, different views have different avatars sizes. Is it worth saving all of them?

I would say: yes!

In my solution with nginx I store every requested size. And this solution works fast.

I am also interested in coding avatar resizing availability as a new feature! Greetings