Skip to content

Instantly share code, notes, and snippets.

@rheinardkorf
Last active October 1, 2021 16:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rheinardkorf/4170464ac3587aae5cbef490f99f855f to your computer and use it in GitHub Desktop.
Save rheinardkorf/4170464ac3587aae5cbef490f99f855f to your computer and use it in GitHub Desktop.
Out of the box ACF is taxing on your site performance, but also CPU load if you have large sites (think 10k+ posts). There are ways to improve ACF by doing things like batch writes or pre-fetching values into the ACF Store. As I create some of these techniques I will add them to this Gist. This will work okay'ish without an object cache, but its…
<?php
/**
* This file contains some hooks to improve ACF performance.
*
* @package rheinardkorf
*/
add_filter(
'acf/pre_load_value',
function( $meta, $post_id, $field ) {
$store = acf_get_store( 'values' );
// Prefetch options into ACF Store.
if ( 'options' === $post_id ) {
// Prefetch site options.
if ( ! $store->has( 'prefetched:options' ) ) {
global $wpdb;
$like = 'option_%';
$prefetch_cache_key = md5( 'acf/pre_load_value/prefetched:options' );
$results = wp_cache_get( $prefetch_cache_key );
if ( empty( $results ) ) {
$results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name LIKE %s", $like ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
// Let the Object Cache LRU take care of expiry.
wp_cache_set( $prefetch_cache_key, $results );
}
foreach ( $results as $result ) {
$key = str_replace( 'options_', '', $result->option_name );
$key = "options:$key";
$store->set( $key, $result->option_value );
}
$store->set( 'prefetched:options', true );
}
} else {
// Prefetch object meta.
if ( ! $store->has( "prefetched:$post_id" ) ) {
$decoded = acf_decode_post_id( $post_id );
$meta_id = $decoded['id'];
$meta_type = $decoded['type'];
$prefetch_cache_key = md5( "acf/pre_load_value/prefetched:$post_id" );
$meta_data = wp_cache_get( $prefetch_cache_key );
if ( empty( $meta_data ) ) {
$meta_data = get_metadata( $meta_type, $meta_id );
// Let the Object Cache LRU take care of expiry.
wp_cache_set( $prefetch_cache_key, $meta_data );
}
foreach ( $meta_data as $field_name => $value ) {
$real_value = is_array( $value ) && 1 === count( $value ) ? array_pop( $value ) : $value;
// Ignore hidden keys.
if ( preg_match( '/^_/', $field_name ) ) {
continue;
}
$store->set( "$post_id:$field_name", $real_value );
}
$store->set( "prefetched:$post_id", true );
}
}
// If value is already fetched then return that value.
$field_name = $field['name'];
if ( $store->has( "$post_id:$field_name" ) ) {
return $store->get( "$post_id:$field_name" );
}
// Fallback.
return $meta;
},
10,
3
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment