Make WordPress Core

Opened 4 months ago

Closed 4 months ago

Last modified 3 days ago

#63717 closed defect (bug) (fixed)

`fetch_feed()` fails to use data stored in transients.

Reported by: peterwilsoncc's profile peterwilsoncc Owned by: peterwilsoncc's profile peterwilsoncc
Milestone: 6.9 Priority: normal
Severity: normal Version: 6.7
Component: External Libraries Keywords: has-patch has-unit-tests has-dev-note
Focuses: performance Cc:

Description (last modified by peterwilsoncc)

Since the SimplePie upgrade in r59141 / ebfb7649ca16

The fetch_feed() function is intended to store a cache of the feed in a transient and use the data for 12 hours.

Since the upgrade the data is being stored as a transient but fails to make use of the data in subsequent requests to the feed. This results in each request to a website making use of the RSS block re-requesting the data on each page load.

Reviewing the database, it appears the data is stored in a transient but the transient is ignored. The following test demonstrates the issue:

<?php /** * Ensure that fetch_feed() is cached on second and subsequent calls. * * @group feed * * @covers ::fetch_feed */ public function test_fetch_feed_cached() { $filter = new MockAction(); add_filter( 'pre_http_request', array( $filter, 'filter' ) ); fetch_feed( 'https://wordpress.org/news/feed/' ); $this->assertSame( 1, $filter->get_call_count(), 'The feed should be fetched on the first call.' ); fetch_feed( 'https://wordpress.org/news/feed/' ); $this->assertSame( 1, $filter->get_call_count(), 'The feed should be cached on the second call.' ); } 

Note: when added to the test suite, this should be placed in the external-http group. The response can be mocked on the pre_http_request filter

Change History (15)

#1 @peterwilsoncc
4 months ago

  • Summary changed from `fetch_feed()` fails to data stored in transients. to `fetch_feed()` fails to use data stored in transients.

#2 @peterwilsoncc
4 months ago

  • Description modified (diff)

This ticket was mentioned in PR #9280 on WordPress/wordpress-develop by @peterwilsoncc.


4 months ago
#3

  • Keywords has-patch has-unit-tests added

Restore caching to the fetch_feed() function.

Initial commit is just the tests.

Trac ticket: https://core.trac.wordpress.org/ticket/63717

#4 follow-up: @peterwilsoncc
4 months ago

  • Milestone changed from Awaiting Review to 6.9

There's an upstream caching bug in 1.8.0 (current version in WordPress) and 1.8.1 (latest SimplePie version).

A fix has been merged in simplepie/simplepie#883 which I've included in the pull request attached to this issue.

It's probably worth upgrading to 1.8.1 with the caching fix included as a patch, however I've noticed that the copy of SimplePie in WP includes two files that are not included in the library so I'd like to clarify why that is. The two files are:

  • src/wp-includes/SimplePie/src/Core.php
  • src/wp-includes/SimplePie/src/Decode/HTML/Entities.php

cc @SergeyBiryukov @jrf for an assist on the extra files in Core.

#5 in reply to: ↑ 4 @SergeyBiryukov
4 months ago

Replying to peterwilsoncc:

It's probably worth upgrading to 1.8.1 with the caching fix included as a patch, however I've noticed that the copy of SimplePie in WP includes two files that are not included in the library so I'd like to clarify why that is. The two files are:

  • src/wp-includes/SimplePie/src/Core.php
  • src/wp-includes/SimplePie/src/Decode/HTML/Entities.php

These files do exist in the library directory:
https://github.com/simplepie/simplepie/blob/1.8.1/library/SimplePie/Core.php
https://github.com/simplepie/simplepie/blob/1.8.1/library/SimplePie/Decode/HTML/Entities.php

I might have mistakenly copied them to src in [59141] / #55604, should be safe to remove.

#6 @peterwilsoncc
4 months ago

Thanks Sergey.

I've included the 1.8.1 update in the linked pull request. It's very minor as the initial import of 1.8.0 included much of the upstream fixes included in the follow up release.

#7 @peterwilsoncc
4 months ago

#62588 was marked as a duplicate.

#8 @peterwilsoncc
4 months ago

Props props props

This was reported earlier and I'd forgotten about the ticket.

During commit, please props @kaygee79 and @oglekler.

#9 @peterwilsoncc
4 months ago

  • Owner set to peterwilsoncc
  • Resolution set to fixed
  • Status changed from new to closed

In 60490:

External Libraries: Upgrade Simple Pie to 1.8.1 (patched).

Upgrades the Simple Pie library to a patched version of Simple Pie 1.8.1. Much of 1.8.1 was included in the 1.8.0 upgrade committed in r59141. The following fixes from the latest release those that remain for this upgrade:

A caching fix not included in Simple Pie 1.8.1 is also included in this upgrade, see simplepie/simplepie#883.

A caching test for fetch_feed() is introduced in this pull request to ensure that the caching patch is included in future upgrades of the library.

Props kaygee79, oglekler, SergeyBiryukov, peterwilsoncc.
Fixes #63717.

This ticket was mentioned in Slack in #core by westonruter. View the logs.


4 weeks ago

#11 @westonruter
6 days ago

I was confused why benchmarking server timing for the homepage with the theme unit test data imported showed a huge improvement in 6.9 over 6.8. It turn out to be due to the Feed widget! When I benchmarked the first page of posts, I saw the huge improvement, but when I benchmarked the second page of posts, the large change went away. It was due to the "Blocks: Widgets" post being on the first page, and this post includes the Feed widget. When I benchmark server timing for just that one post with a Feed widget, the isolated improvement is dramatic:

npm run research -- benchmark-server-timing --url=http://wp68.local/blocks-widgets/ --url=http://wp69.local/blocks-widgets/ --number=100 --diff --output=md 
URL WP 6.8 WP 6.9 Diff (ms) Diff (%)
Response Time (median) 266.57 34.74 -231.83 -87.0%
wp-before-template (median) 11.95 7.86 -4.09 -34.2%
wp-template (median) 252.55 25.56 -226.99 -89.9%
wp-filter-the_content (median) 224.5 9.35 -215.15 -95.8%
wp-total (median) 264.56 33.4 -231.16 -87.4%

This ticket was mentioned in Slack in #core-performance by westonruter. View the logs.


6 days ago

#13 @westonruter
5 days ago

  • Version set to 6.7

#14 @DavidAnderson
4 days ago

I was just investigating why my MySQL binary logs were so large. It was because WordPress saves this transient on every page load. Investigating that, I eventually traced it down to this problem, i.e. specifically the fix in https://github.com/simplepie/simplepie/pull/883/files . This bug causes an SQL UPDATE request as well as an HTTP fetch operation on every single page load - hence the performance impact. And if you're using MySQL binary logging (which you are if you care about being able to roll back your database to any given moment), then that's a lot of logging; in my case, 256KB for every request of the page.

Why would something with this sort of impact (for everyone using a particular core widget) not have gone into a WP 6.8.X release?

#15 @westonruter
3 days ago

  • Keywords has-dev-note added

@DavidAnderson That's a good question. It certainly seems like it would be a good candidate for a minor release. But now that we're a couple weeks away from 6.9, I don't know if that will be done.

Aside: Mentioned in a newly-published dev note: https://make.wordpress.org/core/2025/11/18/wordpress-6-9-frontend-performance-field-guide/#improve-rss-feed-caching

Note: See TracTickets for help on using tickets.