Index: wp-admin/includes/theme.php
===================================================================
--- wp-admin/includes/theme.php	(revision 31889)
+++ wp-admin/includes/theme.php	(working copy)
@@ -408,7 +408,26 @@
  */
 function wp_prepare_themes_for_js( $themes = null ) {
 	$current_theme = get_stylesheet();
+	$prepared_themes = array();
 
+	/**
+	 * Allow overriding the themes returned. Passing a non-empty array will cause
+	 * this function to exit early with that array of theme data. This can allow
+	 * for more aggressive caching on installs with a large number of themes.
+	 *
+	 * @since 4.2.0
+	 *
+	 * @param array      $prepared_themes  An associative array of theme data.
+	 * @param null|array $themes           An array of WP_Theme objects to prepare, if any.
+	 * @param string     $current_theme    The current theme slug.
+	 *
+	 * @return array Default empty array to skip, non-empty array to override.
+	 */
+	$prepared_themes = apply_filters( 'pre_wp_prepare_themes_for_js', $prepared_themes, $themes, $current_theme );
+	if ( is_array( $prepared_themes ) && ! empty( $prepared_themes ) ) {
+		return $prepared_themes;
+	}
+
 	// Make sure the current theme is listed first.
 	$prepared_themes = array( $current_theme => array() );
 
