How to cache the wp_oembed_get() function

The wp_oembed_get() function is not cached by default. Unfortunately, many themes (like Elegant Themes Divi) still use it which leads to your page making many background requests to YouTube and similar video embedding sites. This slows down your pageloads since WordPress has to wait for YouTube to response before showing your page.

If you’re not able to fix your theme, you can add the code below into an mu-plugin or into your themes functions.php file. It will cache embeds that are using wp_oembed_get(). Please note that embeds that fail to resolve (for example: deleted youtube video) will still not be cached. This is due to the way wp_oembed_get() works internally and is not trivial to fix.

<?php
/**
 * Cache wp_oembed_get()
 * Version: 1.0
 */

define('CUSTOM_OEMBED_CACHE_KEY', 'coc_');

function _wp_custom_oembed_cache_key($url, $args) {
  $args_serialized = serialize($args);
  return CUSTOM_OEMBED_CACHE_KEY . md5("{$url}-{$args_serialized}");
}

/**
 * This function caches the result
 */
add_filter('oembed_result', function($data, $url, $args) {
  // Cache result
  set_transient(_wp_custom_oembed_cache_key($url, $args), $data, DAY_IN_SECONDS);
  return $data;
}, 999, 3);

/**
 * This function serves the cached result
 */
add_filter('pre_oembed_result', function($result, $url, $args) {

  // Clean out empty oembed calls caused by Divi
  if(trim($url) === '') {
    return '';
  }

  // Return cached result if available
  if($cached_result = get_transient(_wp_custom_oembed_cache_key($url, $args))) {
    return $cached_result;
  }

  return $result;
}, 2, 3);

Leave a Reply

Your email address will not be published. Required fields are marked *

Markdown is allowed in comments.