Skip to content

Fix author page performance regression - #617

Merged
akirk merged 7 commits into
mainfrom
fix/author-page-performance
Mar 26, 2026
Merged

Fix author page performance regression#617
akirk merged 7 commits into
mainfrom
fix/author-page-performance

Conversation

@akirk

@akirk akirk commented Mar 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • Cache get_feeds() on User object to avoid duplicate term queries (called 3x in author-header.php)
  • Reuse known author in have_posts() loop instead of per-post wp_get_object_terms() lookups via get_post_author()
  • Add static cache to get_actor_metadata_from_attributed_to() to avoid repeated JSON parsing for the same actor across posts
  • Add lazy-loading to User/Subscription get_post_count_by_post_format() matching the pattern in the global version (return ... placeholders instead of running expensive COUNT queries synchronously)

Context

The ccda819 commit added the friends_author_avatar_url filter to header.php, which triggers ActivityPub actor metadata lookups for every post in the loop (previously only status-format posts). Combined with existing N+1 patterns, this made author pages noticeably slow.

Test plan

  • Visit a friend/subscription author page and verify it loads quickly
  • Verify post format counts show ... initially and load correctly on subsequent visits (after transient is set)
  • Verify reblog posts still show correct avatars and author URLs
  • Run CI tests

Test in WordPress Playground

akirk added 7 commits March 26, 2026 16:05
- Cache get_feeds() on User object to avoid duplicate term queries
  (called 3x in author-header.php)
- Reuse known author in have_posts() loop instead of per-post
  wp_get_object_terms() lookups via get_post_author()
- Add static cache to get_actor_metadata_from_attributed_to() to
  avoid repeated JSON parsing for the same actor across posts
- Add lazy-loading to User/Subscription get_post_count_by_post_format()
  matching the pattern in the global version (return placeholders
  instead of running expensive queries synchronously)
Root cause: Remote_Actors::get_avatar_url() triggers the
activitypub_remote_media_url filter which synchronously downloads
avatar images via HTTP when not locally cached (2-3.5s per post).

- Rewrite author_avatar_url filter to read icon directly from
  actor JSON (already in memory) instead of calling get_avatar_url()
- Replace get_avatar_url() in get_actor_metadata_from_attributed_to()
  with get_icon() + object_to_uri() to avoid the same HTTP trap
- Cache User/Subscription objects in get_post_author() to avoid
  recreating them for every post from the same author
Use the cached get_actor_metadata_from_attributed_to() which already
calls get_actor() + get_icon() instead of duplicating the logic.
Removed the force fetching parameter from the get_post_count_by_post_format method and its related logic.
Removed the force fetching parameter from get_post_count_by_post_format method.
@akirk
akirk merged commit 5c419d7 into main Mar 26, 2026
25 checks passed
@akirk
akirk deleted the fix/author-page-performance branch March 26, 2026 20:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant