Hace poco tiempo tuve que lidiar con un proyecto WordPress que su «Galería de Medios«, con unos 30Gb’s de imágenes, tardaba 8 segundos en cargar, demasiado lento para los tiempos de respuesta de internet. Este problema me tuvo durante muchas horas analizando el Core, buscando alternativas de solución y hasta abrí un ticket en la página de soporte de WordPress España por si algún compañero se había topado con el mismo problema. Después de mucho tiempo de lucha pude dar con la solución que describiré en este artículo.

¿Por qué tarda tanto?
La vista de grilla de la Galería de Medios carga las últimas 40 imágenes cargadas mediante una función AJAX (a veces realiza 2 llamadas si tiene más espacio que cubrir en la página).
La función AJAX coge de cada imagen todas sus miniaturas (full, large, medium_large, medium, thumbnail y todas las personalizadas) para obtener sus metadatos y luego calcular cuál de ellas es la más óptima para visualizar en la «Galería de Medios». El proceso parece estúpido, ya que con los thumbnails nos bastaría para mostrar las imágenes, pero en realidad la petición AJAX reutiliza una función del Core de WordPress llamada wp_prepare_attachment_for_js
que está pensada y codificada para devolver toda esta información a otras funciones.
Por fortuna, está tan bien diseñada que se han acordado de poner algunos filtros, que utilizaremos para reducir el tiempo de carga de las imágenes, y un excelente comentario que me ha dado el indicio para llegar a la solución (línea 3186 del fichero wp-includes/media.php).
<?php
// Loop through all potential sizes that may be chosen. Try to do this with some efficiency.
// First: run the image_downsize filter. If it returns something, we can use its data.
// If the filter does not return something, then image_downsize() is just an expensive
// way to check the image metadata, which we do second.
// TRADUCCIÓN AL CASTELLANO
// La siguiente función iterará sobre todos los potenciales tamaños de imágenes a elegir. Trata de ejecutar esta función con eficiencia.
// Primero: Llama el filtro image_downsize. Si devuelve algún valor, lo utilizaremos.
// caso contrario, ejecutaremos la función image_downsize() para obtener los metadatos, aunque es un proceso muy costoso.
Con toda esta información es hora de que nos pongamos manos a la obra.
Solución al problema
Primero vamos a limitar la función para que no recoja todas las miniaturas, con el thumbnail nos bastaría. Para ello utilizamos el siguiente filtro:
<?php
/*
* Con esta función estamos indicando que la función
* devuelva solamente los datos del thumbnail de la imagen.
*/
function mg_fix_select_only_thumbnails() {
return array(
'thumbnail' => __('Thumbnail'),
);
}
add_filter( 'image_size_names_choose', 'mg_fix_select_only_thumbnails' );
Pero eso no es todo, si releemos el comentario del punto anterior nos faltaría llamar al filtro image_downsize
el cual debe devolver los metadatos de la imagen:
<?php
function mg_fix_scaled_image( $downsize, $attachment_id, $size ) {
// Quitamos el filtro primero para no entrar en bucle infinito
remove_filter( 'image_downsize', 'mg_fix_scaled_image', 10 );
$result = wp_get_attachment_image_src( $attachment_id, $size );
// Una vez obtenido los metadatos del attachment restituimos el filtro
add_filter( 'image_downsize', 'mg_fix_scaled_image', 10, 3 );
return $result;
}
add_filter('image_downsize', 'mg_fix_scaled_image', 10, 3);
¿Cómo corroborar la solución?
Por supuesto que tendremos que notar una mejora en el tiempo de respuesta de carga de la Galería de Medios, pero también podemos chequearlo en la pestaña «Network» de Chrome: La respuesta de la función AJAX solo debería estar devolviendo los valores del thumbnail y de la imagen original.

Conclusión
Espero que esta solución pueda ayudar a muchas personas ya que por mi parte he buscado intensamente en internet sin haber dado con algún artículo similar que me diera algo de luz en el problema. Ahora sí, a navegar tranquilamente por la Galería de Medios de WordPress.
Angel
Hola Mauricio, actualmente herede una web con mas de 10GB de imágenes.
Al dirigirme a escritorio de WP -> Medios -> Añadir nuevo
No da problemas al cargar las Imágenes.
Pero al dirigirme a un Post y cargar la imagen destacada o una imagen dentro del contenido la barra de carga se queda pegada y no avanza.
Implemente tu solución y no logre solventar el inconveniente.
Help !!
Mauricio Gelves
Hola Ángel:
Si bien mi artículo sirve para muchos casos siempre hay excepciones a la regla. Habría que hacer un poco más de análisis de por qué se queda bloqueada tu web, tal vez haya más plugins que estén afectando al upload de imágenes.
Te diría que hagas un backup, que lo montes en local (en tu ordenador) y que pruebes desactivando todos los plugins para ver si puedes dar con el hilo del problema.
¡Un saludo y suerte!
Mauricio
cmacias
Muy buena solución. Enhorabuena :))
Mauricio Gelves
Muchas gracias Carlos.
Fermín
Genial, me ha encantado además la aproximación al problema, documentación, solución y testeo de la misma.
Un crack.
Abrazos.
Mauricio Gelves
Muchas gracias Fermín.
Un saludo,
Mauricio
Gerardo Garcia Asensio
¡Gracias Mauricio!
Vi el ticket en el soporte hace unos días, y aunque nunca me encontré ese problema me quede con la curiosidad de como se solucionaria.
Gracias por documentarlo y compartirlo, eres un crack!
Un abrazo.
Mauricio Gelves
¿Cómo no compartirlo con la comunidad?
Un abrazo Gerardo!