Is there an easy way to ensure that external feeds (via fetch_feed()
) are only fetched via cron, and not when a regular user visits the site? This is for performance reasons, I want to minimize the page load time.
The only time a feed should load in a normal request are probably when the cache is empty (the first time it is loaded) and maybe when a logged in user is visiting the page (because I will be the only one with a user account).
3 Answers
My recommendation would be to set up a wrapper for fetch_feed()
. Call the wrapper function through WordPress’ cron and you shouldn’t have an issue.
So something like:
function schedule_fetch_feeds() {
if ( ! wp_next_scheduled( 'cron_fetch' ) ) {
wp_schedule_event( time(), 'hourly', 'cron_fetch', 'http://blog1.url/feed' );
wp_schedule_event( time(), 'hourly', 'cron_fetch', 'http://blog2.url/feed' );
}
}
function fetch_feed_on_cron( $url ) {
$feed = fetch_feed( $url );
delete_transient( "feed-" . $url );
set_transient( "feed-" . $url, $feed, 60*60 );
}
add_action( 'wp', 'schedule_fetch_feeds' );
add_action( 'cron_fetch', 'fetch_feed_on_cron', 10, 1 );
Keep in mind, I haven’t had a chance to test this yet! But it should create cron jobs to grab each of your feeds and store the feeds temporarily in transients. The transients have 1-hour expirations, because the cron should realistically be updating them every hour anyway.
You can pull the feeds out of the transients using:
function get_cached_feed( $url ) {
$feed = get_transient( "feed-" . $url );
if ( $feed ) return $feed;
$feed = fetch_feed ( $url );
set_transient( "feed-" . $url, $feed, 60*60 );
return $feed;
}
If the transient exists, the function grabs it and returns it. If it doesn’t, the function will grab it manually, cache it, and still return it.