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

Avatar Performance #26585

Open
3 tasks
butonic opened this issue Nov 8, 2016 · 12 comments
Open
3 tasks

Avatar Performance #26585

butonic opened this issue Nov 8, 2016 · 12 comments

Comments

@butonic
Copy link
Member

butonic commented Nov 8, 2016

In my data/avatars folder i see a lot of empty 2 char folders. likely created by https://github.com/owncloud/core/blob/master/lib/private/AvatarManager.php#L98

They somehow also made it into the oc_filecache with a size of -1

this causes the avatar folder to also stay at a size of -1 because the folder is only scanned shallow: all empty folders stay at -1.

This causes a (shallow) filescan when trying to get an avatar image via eg
http://localhost/owncloud/index.php/avatar/admin/28. In my case this takes 400ms for 240 2 char folders in the avatar folder.

AFAICT introduced with #26124

This is made worse by the Cache-Control: no-store, no-cache, must-revalidate header of the http://localhost/owncloud/index.php/avatar/admin/28 response because we call the url twice when navigating to http://localhost/owncloud/index.php/apps/files/?dir=/ @PhilippSchaffrath has details on why we do that.

The header is set in https://github.com/owncloud/core/blob/master/core/Controller/AvatarController.php#L138. For users without an avatar image also because the DataResponse in https://github.com/owncloud/core/blob/master/core/Controller/AvatarController.php#L124 and https://github.com/owncloud/core/blob/master/core/Controller/AvatarController.php#L130 is converted to a JSONResponse in https://github.com/owncloud/core/blob/master/lib/public/AppFramework/Controller.php#L92 which overwrites the Cache-Control with the default from the JSONResponse / Response ('Cache-Control' => 'no-cache, must-revalidate').

Replacing the DataResponse with a JSONResponse would allow caching the avatar, eg:

--- a/core/Controller/AvatarController.php
+++ b/core/Controller/AvatarController.php
@@ -28,6 +28,7 @@ namespace OC\Core\Controller;
 
 use OCP\AppFramework\Controller;
 use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\JSONResponse;
 use OCP\AppFramework\Http\DataResponse;
 use OCP\AppFramework\Http\DataDisplayResponse;
 use OCP\Files\NotFoundException;
@@ -121,7 +122,7 @@ class AvatarController extends Controller {
                        $resp->setETag($avatar->getEtag());
                } catch (NotFoundException $e) {
                        $user = $this->userManager->get($userId);
-                       $resp = new DataResponse([
+                       $resp = new JSONResponse([
                                'data' => [
                                        'displayname' => $user->getDisplayName(),
                                ],
@@ -135,7 +136,7 @@ class AvatarController extends Controller {
                }
 
                $resp->addHeader('Pragma', 'public');
-               $resp->cacheFor(0);
+               $resp->addHeader('Cache-Control', 'privat, max-age=600');
                $resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT')));
 
                return $resp;

There is another DataResponse that can be replaced, but my Linux VM wit PHPStorm just froze ...

In any case, we should

  • not create empty 2 char folders in the avatars folder
  • fix the multiple loading of the avatar,
  • we should send a better Cache-Control header, eg 'privat, max-age=600' ... any opinion on the max-age?

cc @PVince81 @DeepDiver1975 @IljaN

@DeepDiver1975
Copy link
Member

Afaik we need to add Etag's for proper caching.

@butonic
Copy link
Member Author

butonic commented Nov 9, 2016

if an Etag: "123" header is present in a response the browser will send a request with an If-None-Match: "123" header when the max-age in a Cache-Control header has passed. A Last-Modified header on the response works in similar way: the browser will send the If-Modified-Since header. Etag and Last-Modified are called Verification headers. Also see https://www.mnot.net/cache_docs/#VALIDATE

ProTip: Testing caching can only be done by pressing enter in the URL, F5 causes the browser to send a request with Cache-Control: max-age=0 header instead of using the local cache. The server will likely respond with a 304, but a request is still made. From http://stackoverflow.com/a/37674029

When you press F5 in Chrome, it will always send requests to the server. These will be made with the Cache-Control:max-age=0 header. The server will usually respond with a 304 (Not Changed) status code.

When you press Ctrl+F5 or Shift+F5, the same requests are performed, but with the Cache-Control:no-cache header, thus forcing the server to send an uncached version, usually with a 200 (OK) status code.

If you want to make sure that you're utilizing the local browser cache, simply press Enter in the address bar.

@butonic
Copy link
Member Author

butonic commented Nov 9, 2016

oh and apache handles the generation of etags for static files

@PVince81
Copy link
Contributor

oh and apache handles the generation of etags for static files

But none of the files in OC are static, right ? Because everything goes through PHP to have the app/theme/routing overloading magic.

@butonic
Copy link
Member Author

butonic commented Nov 10, 2016

css, js and woff files are

@phisch
Copy link
Contributor

phisch commented Nov 11, 2016

7 days might be a little bit too long to cache the avatars request. 1 or 2 hours would be fine!

@PVince81
Copy link
Contributor

PVince81 commented Apr 6, 2017

any update ?

@PVince81 PVince81 modified the milestones: 10.0.1, 10.0 Apr 26, 2017
@PVince81
Copy link
Contributor

no update, moving to triage for rescheduling

@ownclouders
Copy link
Contributor

Hey, this issue has been closed because the label status/STALE is set and there were no updates for 7 days. Feel free to reopen this issue if you deem it appropriate.

(This is an automated comment from GitMate.io.

@ownclouders
Copy link
Contributor

Hey, this issue has been closed because the label status/STALE is set and there were no updates for 7 days. Feel free to reopen this issue if you deem it appropriate.

(This is an automated comment from GitMate.io.)

@ownclouders
Copy link
Contributor

Hey, this issue has been closed because the label status/STALE is set and there were no updates for 7 days. Feel free to reopen this issue if you deem it appropriate.

(This is an automated comment from GitMate.io.)

@PVince81
Copy link
Contributor

moving to backlog as there is currently no active development on this topic

@PVince81 PVince81 modified the milestones: development, backlog Oct 12, 2018
@butonic butonic removed their assignment Feb 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants