Project

General

Profile

Actions

Feature #2609

closed

Improved caching for front-page widgets

Added by Boone Gorges almost 11 years ago. Updated over 9 years ago.

Status:
Resolved
Priority name:
Low
Assignee:
Category name:
Home Page
Target version:
Start date:
2013-05-30
Due date:
% Done:

0%

Estimated time:
Deployment actions:

Description

See also #2809, which is another idea for speeding up the homepage.

We have three dynamic widgets on the home page. Each requires a fairly hefty query. I was thinking we might see noticeable improvements if we employed some sort of caching for the widgets. Something like: Put the markup of the inner div into a transient that expires every minute or two. In cases where the widget has different tabs fetched by AJAX (groups, members), store each one of the values.

Actually, we might cache some sorts of data even more intelligently. Eg, the Members > Newest cache only needs to be busted when a new member joins the site. The Active sorts probably need to have time-based storage, since people are active on the site at least several times a minute.

Ray, could I ask you to think about these ideas and let me know what you think is (a) feasible, and (b) worth doing? Thanks!


Related issues

Related to CUNY Academic Commons - Feature #2591: Should we be displaying rotating tweets on the CAC homepage?RejectedDominic Giglio2013-05-21

Actions
Actions #1

Updated by Matt Gold almost 11 years ago

Smart. Thanks!

Actions #2

Updated by Raymond Hoh almost 11 years ago

Are we running into load issues on the homepage?

Caching the entire contents of the widgets shouldn't be too hard with a decent transient library like:
https://github.com/markjaquith/WP-TLC-Transients

However, caching each widget state (Newest, Active) will be a bit complicated since both member and group widgets are from BP and rely on AJAX. I'm thinking that this might be achievable by object buffering the members / groups loop and do our transient checking there

(Update: that's not going to work b/c object buffering will still run the queries. Will probably have to unhook BP's AJAX action and create our own AJAX handler.)

If we are only worried about load issues, then perhaps it might be worth considering using a caching plugin like WP Super Cache to take advantage of its frontpage caching option. Only logged-out users will get the cached frontpage.

Boone, let me know what you think.

Actions #3

Updated by Boone Gorges almost 11 years ago

  • Priority name changed from Normal to Low
  • Target version changed from 1.5 to Future release

Are we running into load issues on the homepage?

It's running a bit slowly, especially on mobile devices. I know that it's probably due to too many assets loading (see #2608), but I thought this could be a nice optimization, and potentially something that could be passed upstream.

It's probably the case that the widgets as they currently stand in BP - both the ajax handlers and the widget class itself - would need to be modified to make all of this stuff work.

That said, let's make it a low priority, and focus on other optimizations first.

Actions #4

Updated by Raymond Hoh almost 11 years ago

Was just looking at the number of DB queries on the frontpage and it's close to 300!

A couple of things we can consider caching other than the widgets include:

  • The nav menu under the CAC logo
  • The slider
Actions #5

Updated by Boone Gorges about 10 years ago

  • Target version changed from Future release to 1.6

Given some of the recent focus in BuddyPress core development on these issues, I think it's a good time to tackle this. Ray, I'm going to keep this assigned to you, but I'm going to be taking a look at it too. Feel free to use this ticket as a driver for some BP core fixes, where appropriate. I realize that this may be limiting in some ways because we're not currently using an object cache on the Commons, but presumably most of our BP core fixes will center on object caching. But this could also be a space for you to think about experimenting with some of your ideas about Etags and browser-based caching.

Actions #6

Updated by Boone Gorges about 10 years ago

  • Category name set to Home Page
Actions #7

Updated by Boone Gorges almost 10 years ago

  • Target version changed from 1.6 to 1.7
Actions #8

Updated by Raymond Hoh over 9 years ago

I've added a first pass of BP widget caching in the 1.7.x branch in commit a17162ec51.

Some dev notes:

  • A whitelist of BP widgets are cached. By default, this includes all the major BP widgets like the Members, Groups, Blog Posts, Who's Online, Recently Active Members and Friends widgets.
  • Each BP widget is cached as a site transient. I used a site transient since CAC doesn't run an object cache so any site could benefit from this plugin.
  • Since a BP widget can be used more than once with different settings, each instance of a BP widget is saved as a key-value pair in this site transient.
  • Support for invalidation at various junctures including widget deletion and updating of widget settings.
  • No unit tests yet (I know, I know).
  • No cache support for widgets with AJAX tabs, but I don't think this is a big issue.

I'd like to test this on cdev, but cdev currently has a bunch of uncommitted files and I didn't want to override anything.

Feedback welcome.

Actions #9

Updated by Boone Gorges over 9 years ago

Hi Ray - I'm going to spend some more time with the code in the next day or two, but in the meantime I have pulled the changes to cdev. (/var/www/html is still an awful mess, but at least your code was pulled down)

Actions #10

Updated by Raymond Hoh over 9 years ago

Thanks Boone for getting the plugin on cdev. Just tested the plugin and it saves 30 DB queries for the default BP widgets on the CAC homepage.

I just added a new commit on 1.7.x branch that will cache CAC's custom Recent Blog Posts widget. This will save us an additional 104 DB queries (!).

So now, we're at a more respectable 118 DB queries on the homepage (down from 252 queries).

We could also cache the rotating slider widget with BP Widget Cache, which would save us an additional 58 DB queries. Would need to also write a cache invalidation function for the slider, but that should be trivial.

And if we really wanted to save more, we could cache the nav menu under the CAC logo, which takes about 8 DB queries to render.


One caveat so far that I've encountered is the active timestamps (for members and groups) are wrong since it's grabbing the cached timestamp. One way to remedy this is we'd need to add a data-timestamp attribute to the timestamp container and then use javascript to switch out the timestamp with the real one.

Actions #11

Updated by Matt Gold over 9 years ago

very cool.

Actions #12

Updated by Boone Gorges over 9 years ago

Latest changes pulled to cdev. Just hitting refresh I can tell the difference. Nice job with the BP patch too - I've left comments there regarding upstream integration.

We could also cache the rotating slider widget with BP Widget Cache, which would save us an additional 58 DB queries. Would need to also write a cache invalidation function for the slider, but that should be trivial.

Yeah! Go for it.

One caveat so far that I've encountered is the active timestamps (for members and groups) are wrong since it's grabbing the cached timestamp. One way to remedy this is we'd need to add a data-timestamp attribute to the timestamp container and then use javascript to switch out the timestamp with the real one.

Hrm, yeah. Actually, adding that data attribute is probably not the worst idea in BuddyPress itself. But does this mean we'd have to implement bp_core_time_since() in JS? That sounds kinda unpleasant.

Actions #13

Updated by Raymond Hoh over 9 years ago

Left some feedback on the BP ticket.

I've just added widget caching to the rotating slider widget on 1.7.x branch. (I've applied the changes directly to cdev.) But, I just remembered that the rotating slider widget has an option to order the slides. Right now, cdev uses the date descending order, which I'm guessing CAC uses as well. This works fine, but if CAC uses the random order, then we'll need to revert the latest commit. Or I'll need to add some filters in BP Widget Cache so we can bail out of caching in instances like these.

Actually, adding that data attribute is probably not the worst idea in BuddyPress itself. But does this mean we'd have to implement bp_core_time_since() in JS? That sounds kinda unpleasant.

I've done something like this a long time ago using a JS library that implements relative time. It wouldn't be that hard. But if we're doing this for BP core, this would mean adding another JS library of course. Will create a new ticket for this on BP Trac.

Actions #14

Updated by Boone Gorges over 9 years ago

I've done something like this a long time ago using a JS library that implements relative time. It wouldn't be that hard. But if we're doing this for BP core, this would mean adding another JS library of course. Will create a new ticket for this on BP Trac.

Nice. Note that for BP, we have to be localizable too. I have a feeling that'd mean writing our own shim or wrapper for whatever existing libraries might exist.

Actions #15

Updated by Raymond Hoh over 9 years ago

Note that for BP, we have to be localizable too.

Right. jQuery timeago has localization support. Would be quite easy to do i18n with this plugin. I think this was the library I used in the past as well.

FYI, we're now down to 60 queries!

Actions #16

Updated by Raymond Hoh over 9 years ago

Just added a first pass at dynamically adjusting the relative time using JS to 1.7.x branch. It's live on cdev.

On the CAC homepage, the strings that are affected are the "active X ago" in the Members and Groups widget and the "x ago" string in the Recent Blog Posts widget.

For the JS library, I'm using livestamp.js since it has good localization support.

Actions #17

Updated by Boone Gorges over 9 years ago

  • Status changed from Assigned to Resolved

I've been playing with these customizations over the last few months, and I've been really impressed. Thanks for all your work on them, Ray.

I'm marking this ticket resolved, as I think we've done all we need to do for the 1.7 milestone. If we want to move further on this project, let's consider reopening, or creating a new ticket with details against another milestone.

Actions

Also available in: Atom PDF