User more info - Cache results and render optimization

When a user click on author avatar on a side of post, A small inline box will expand with additional user information.
most of the information in this box is pulled dynamically from the server (ajax).

what is the issue?

  1. every time the user click on the avatar a request will be issued to the server. you clicked on the same avatar and toggled it on 10 times.

the server will get 10 ajax requests to

AJAX GET https://meta.discourse.org/users/codinghorror.json

There are two losers here

  1. user: the user will have a slower responses due to the content not being cached.
  2. The server no cache mean the server will get more requests.

Possible solutions:

  1. Add Browser cache support
    I tested the following code in console, and for the life of it I don’t understand why chrome/firefox does not cache the request
$.ajax({
url:"https://meta.discourse.org/users/codinghorror.json",
cache:true,
dataType: 'json',
//ifModified : true,
headers: {
      'Cache-Control': 'max-age=60' 
    }
})

2 . Cache results in the app logic.

conclusions

It will probably be ideal to have a proper caching on the browser level, with a reasonable expiry.
But having the app cache this type of requests temporarily is also a feasible solution.

Another possible optimization

The info of that box is rendered in div#poster-expansion The div is being reused on the page for different users info.
When you close the box it is just hidden with css.
We can save some dom manipulation, by checking when you open the box if the request is for the same user just show the box. do not reload or re render the box with the json data.

Why does the Ajax request not cache

In the test ajax request (see code above), I could not trigger the browser to cache the request.
There is no obvious header in the server response to should prevent the browser from caching.
I suspect that it is possible that the request is not cached due to the combination of an ajax request over SSL.
I couldn’t find anything to back that up yet.

I’m not even sure if there is an issue. I’ve been perusing Meta for a couple of months now and clicked on avatars… three times? Maybe fivish. Tops.

Even if someone had a keen interest in everybody else’s biography, there’s no reason to click the same user’s avatar ten times in a row. In fact, caching the data means that our hypothetical stalker would miss out on any new badges the watched user gets unless they clear the app-level cache by way of refreshing the entire page.

I am all for optimising but I think there are plenty other spots that need to be optimised first.

3 Likes

@elberet I guess there are not many interesting faces/people here, if you are not checking each and every avatar.
the base use case that you can look at is if you check a person, you closed the info box quickly and then wanted to see it again. just for this it is worth having short term caching, it does not make sense to make an identical ajax call in 2-3 seconds difference.

@sam
The user info box is a possible future optimization an it is just an example of the missing cache capability.
I did bring up the point that it may not be possible to cache ajax request on meta ( possibly at all?) I am not sure how much caching is needed on ajax requests. but the user box is an example.

I couldn’t check my code on discourse without secure HTTP(s) to confirm if it is SSL that prevent caching on ajax requests. or may be another header in the response.

Do you know of a Discourse instance that allow http requests without redirect to https?, So I can test and satisfy my curiosity?

Which ones do you consider we should take a look first? regarding optimization.

I’m new to discourse community and I would like to start contributing, so if you point me in the right direction I might be able to help here and there :slight_smile:

Best wishes,

Nico.

1 Like

It’s precipitous that this got bumped. I’ve noticed that user cards take a LONG time to pop up, over a second for me, so I have been thinking about this lately. I feel like the user card should come up faster (maybe with placeholders?) and dynamically query the info it needs @sam.

3 Likes

I vaguely recall @eviltrout? maybe had the placeholder solution in initial versions, but it was a bit jarring.

I had a quick look and your user.json takes about 220ms, wack on a a roundtrips and yeah this can take a second (at least from some geos)

Agree it would be nice to do something better here, it is purely a UX change. I wonder how @awesomerobot feels here? We could certainly kick off a 400ms subtle animation (grabbing data at the start) and then finalizing the card once the animation is over?

@venarius really loves this kind of stuff, maybe do a mockup here?

I would recommend picking something a tiny bit smaller here as a first contribution, this is quite tricky to wire up. Have you had a look at:

7 Likes

Yeah just some kind of slightly better responsiveness here, where we defer the card work a bit and show an animation, even, would be a marked improvement. It doesn’t need to be perfect just “better than what we have now” … currently user cards are really clunky and slow to appear for me, and I have a very fast connection and I’m also close to many of the servers :confused:

Just clicking on your user card, it’s almost a full second before anything happens on my screen at all … really closer to two seconds :confounded:

3 Likes

Also as an idea I have would be maybe to implement something like http://instantclick.io here? It starts the ajax call as soon as the user hovers the avatar and shows intention to click on it.

There is a test at Test your click speed - InstantClick that shows that you can easily save about 400ms of loading time with this. Even on mobile.

4 Likes

Hmmm we would need to be ultra careful with that, intent is something that is hard to ultra reliably determine, people could be just moving the mouse pointer around.

This would have to start off as an experimental thing.

3 Likes

Some more ideas which are probably on the more easier side to implement:

  • Show a loading circle on top of the avatar after the user clicked on it as an indication for “something is about to happen”

  • Instantly show the modal and show a loading circle until the content is loaded in

3 Likes

This would be better from my perspective. Even if the user card “bounces” and resizes a bit. Because certainly at minimum we know the avatar and username on click, right?

5 Likes

Agreed. I think showing the avatar/username and a spinner while everything else loads is the simplest way to go. The biggest causes for jitter would be the background images and bio… with some layout adjustments the background image loading jitter can probably be avoided… everything else is relatively consistent.

4 Likes

The first version of the user cards I implemented was definitely instantaneous and based on the information we already had in memory with more loading happening afterwards. I imagine it changed at some point either accidentally or because people find the quick change in formatting to be jarring.

4 Likes

Just opened a PR with a first mockup for this :slight_smile:

https://github.com/discourse/discourse/pull/7380

5 Likes

Does this look OK @sam?

I find the spinner here somewhat jarring:

We should have username/name/title and low res image on the page, not following why we can not start with that?

7 Likes

Because as far as I see here, the user modal gets only called with the username of the user. data-user-card={{username}}. That’s why it only knows the username.

Is there a way for me to get the other information without having to do another request to the backend?

I am not sure what the perfect solution here is or even if we will all be perfectly happy with the partial card -> full card transition.

I think we can use the Store to look up a user in the cache which is free from the component? @eviltrout ?

2 Likes

The store would work in many cases, but there is still lots of code that does not use the store. Some is historical, some is HTML that is pre-baked.

I don’t recall if the topic view uses it (I think it does), which might be 90% of the time the user wants to pop up a card. It’s worth trying out.

3 Likes