Improve shortcode performance

Queries are cached as Transients for 5 Minutes, which is not much but help for high traffic that cannot be cached normally (e.g. logged-in users).
This commit is contained in:
Tetrakern 2023-08-03 13:17:32 +02:00
parent 35f88121c3
commit 9ed7e08868
14 changed files with 149 additions and 21 deletions

View File

@ -214,6 +214,11 @@ if ( ! defined( 'FICTIONEER_CHAPTER_FOLDING_THRESHOLD' ) ) {
define( 'FICTIONEER_CHAPTER_FOLDING_THRESHOLD', 5 );
}
// Integer: Expiration time for shortcode Transients (-1 to disable)
if ( ! defined( 'FICTIONEER_SHORTCODE_TRANSIENT_EXPIRATION' ) ) {
define( 'FICTIONEER_SHORTCODE_TRANSIENT_EXPIRATION', 300 );
}
/*
* Booleans
*/

View File

@ -567,4 +567,32 @@ if ( ! function_exists( 'fictioneer_get_last_story_or_chapter_update' ) ) {
}
}
// =============================================================================
// PURGE SHORTCODE TRANSIENTS
// =============================================================================
/**
* Purge all shortcode Transients
*
* @since Fictioneer 5.4.9
*
* @param int $post_id Updated post ID.
*/
function fictioneer_purge_shortcode_transients( $post_id ) {
// Prevent multi-fire
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) return;
if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) return;
// Delete Transients (fast)
fictioneer_delete_transients_like( 'fictioneer_shortcode' );
}
if ( FICTIONEER_SHORTCODE_TRANSIENT_EXPIRATION > 0 ) {
add_action( 'save_post', 'fictioneer_purge_shortcode_transients' );
add_action( 'untrash_post', 'fictioneer_purge_shortcode_transients' );
add_action( 'trashed_post', 'fictioneer_purge_shortcode_transients' );
add_action( 'delete_post', 'fictioneer_purge_shortcode_transients' );
}
?>

View File

@ -1,5 +1,42 @@
<?php
// =============================================================================
// GET SHORTCODE TRANSIENT
// =============================================================================
if ( ! function_exists( 'fictioneer_shortcode_query' ) ) {
/**
* Returns query for shortcode
*
* @since 5.4.9
*
* @param array $args Query arguments.
*
* @return WP_Query The query result.
*/
function fictioneer_shortcode_query( $args ) {
// Transient for shortcodes disabled or in admin panel?
if ( FICTIONEER_SHORTCODE_TRANSIENT_EXPIRATION < 1 || is_admin() ) {
return new WP_Query( $args );
}
// Setup
$transient_key = 'fictioneer_shortcode_' . md5( serialize( $args ) );
$transient = get_transient( $transient_key );
// Query
if ( empty( $transient ) ) {
$result = new WP_Query( $args );
set_transient( $transient_key, $result, FICTIONEER_SHORTCODE_TRANSIENT_EXPIRATION );
} else {
$result = $transient;
}
return $result;
}
}
// =============================================================================
// SHORTCODE-BASED RELATIONSHIPS
// =============================================================================
@ -842,19 +879,19 @@ function fictioneer_shortcode_chapter_list( $attr ) {
if ( empty( $chapters ) ) return $empty;
// Query chapters
$chapter_query = new WP_Query(
array(
'post_type' => 'fcn_chapter',
'post_status' => 'publish',
'post__in' => $chapters,
'ignore_sticky_posts' => true,
'orderby' => 'post__in', // Preserve order from meta box
'posts_per_page' => -1, // Get all chapters (this can be hundreds)
'no_found_rows' => false, // Improve performance
'update_post_term_cache' => false // Improve performance
)
$query_args = array(
'post_type' => 'fcn_chapter',
'post_status' => 'publish',
'post__in' => $chapters,
'ignore_sticky_posts' => true,
'orderby' => 'post__in', // Preserve order from meta box
'posts_per_page' => -1, // Get all chapters (this can be hundreds)
'no_found_rows' => true, // Improve performance
'update_post_term_cache' => false // Improve performance
);
$chapter_query = fictioneer_shortcode_query( $query_args );
// Check query for items
if ( ! $chapter_query->have_posts() ) return $empty;

View File

@ -1706,4 +1706,62 @@ if ( ! function_exists( 'fictioneer_get_story_blog_posts' ) ) {
}
}
// =============================================================================
// DELETE TRANSIENTS THAT INCLUDE A STRING
// =============================================================================
if ( ! function_exists( 'fictioneer_delete_transients_like' ) ) {
/**
* Delete Transients with a like key and return the count deleted
*
* @since 5.4.9
*
* @param string $partial_key String that is part of the key.
* @param boolean $fast Optional. Whether to delete with a single SQL query or
* loop each Transient with delete_transient(), which can
* trigger hooked actions (if any). Default true.
*
* @return int Count of deleted Transients.
*/
function fictioneer_delete_transients_like( $partial_key, $fast = true ) {
// Globals
global $wpdb;
// Setup
$count = 0;
// Fast?
if ( $fast ) {
// Prepare SQL
$sql = $wpdb->prepare(
"DELETE FROM $wpdb->options WHERE `option_name` LIKE %s OR `option_name` LIKE %s",
"%_transient%{$partial_key}%",
"%_transient_timeout%{$partial_key}%"
);
// Query
$count = $wpdb->query( $sql ) / 2; // Count Transient and Transient timeout as one
} else {
// Prepare SQL
$sql = $wpdb->prepare(
"SELECT `option_name` AS `name` FROM $wpdb->options WHERE `option_name` LIKE %s",
"_transient%{$partial_key}%"
);
// Query
$transients = $wpdb->get_col( $sql );
// Build full keys and delete
foreach ( $transients as $transient ) {
$key = str_replace( '_transient_', '', $transient );
$count += delete_transient( $key ) ? 1 : 0;
}
}
// Return count
return $count;
}
}
?>

View File

@ -61,7 +61,7 @@ if ( ! empty( $args['excluded_cats'] ) ) {
$query_args = apply_filters( 'fictioneer_filter_shortcode_latest_chapters_query_args', $query_args, $args );
// Query chapters
$entries = new WP_Query( $query_args );
$entries = fictioneer_shortcode_query( $query_args );
?>

View File

@ -62,7 +62,7 @@ if ( ! empty( $args['excluded_cats'] ) ) {
$query_args = apply_filters( 'fictioneer_filter_shortcode_latest_chapters_query_args', $query_args, $args );
// Query chapters
$entries = new WP_Query( $query_args );
$entries = fictioneer_shortcode_query( $query_args );
?>

View File

@ -56,7 +56,7 @@ if ( ! empty( $args['excluded_cats'] ) ) {
$query_args = apply_filters( 'fictioneer_filter_shortcode_latest_posts_query_args', $query_args, $args );
// Query post
$latest_entries = new WP_Query( $query_args );
$latest_entries = fictioneer_shortcode_query( $query_args );
?>

View File

@ -58,7 +58,7 @@ if ( ! empty( $args['excluded_cats'] ) ) {
$query_args = apply_filters( 'fictioneer_filter_shortcode_latest_recommendations_query_args', $query_args, $args );
// Query chapters
$entries = new WP_Query( $query_args );
$entries = fictioneer_shortcode_query( $query_args );
?>

View File

@ -59,7 +59,7 @@ if ( ! empty( $args['excluded_cats'] ) ) {
$query_args = apply_filters( 'fictioneer_filter_shortcode_latest_recommendations_query_args', $query_args, $args );
// Query recommendations
$entries = new WP_Query( $query_args );
$entries = fictioneer_shortcode_query( $query_args );
?>

View File

@ -71,7 +71,7 @@ if ( ! empty( $args['excluded_cats'] ) ) {
$query_args = apply_filters( 'fictioneer_filter_shortcode_latest_stories_query_args', $query_args, $args );
// Query stories
$entries = new WP_Query( $query_args );
$entries = fictioneer_shortcode_query( $query_args );
?>

View File

@ -68,7 +68,7 @@ if ( ! empty( $args['excluded_cats'] ) ) {
$query_args = apply_filters( 'fictioneer_filter_shortcode_latest_stories_query_args', $query_args, $args );
// Query stories
$entries = new WP_Query( $query_args );
$entries = fictioneer_shortcode_query( $query_args );
?>

View File

@ -75,7 +75,7 @@ if ( ! empty( $args['excluded_cats'] ) ) {
$query_args = apply_filters( 'fictioneer_filter_shortcode_latest_updates_query_args', $query_args, $args );
// Query stories
$entries = new WP_Query( $query_args );
$entries = fictioneer_shortcode_query( $query_args );
?>

View File

@ -76,7 +76,7 @@ if ( ! empty( $args['excluded_cats'] ) ) {
$query_args = apply_filters( 'fictioneer_filter_shortcode_latest_updates_query_args', $query_args, $args );
// Query stories
$entries = new WP_Query( $query_args );
$entries = fictioneer_shortcode_query( $query_args );
?>

View File

@ -61,7 +61,7 @@ if ( ! empty( $args['excluded_cats'] ) ) {
$query_args = apply_filters( 'fictioneer_filter_shortcode_showcase_query_args', $query_args, $args );
// Query collections
$query = new WP_Query( $query_args );
$query = fictioneer_shortcode_query( $query_args );
?>