Clásicos Básicos es un museo vivo del videojuego clásico en español: más de 870 fichas de PC, Amiga, Spectrum, Amstrad y NES, más foros, podcast y el canal CLABA TV. El reto no era el diseño. Era que un archivo de ese tamaño no se comiera la página.
Un catálogo grande no es un blog grande
WordPress aguanta perfectamente 870 entradas. Lo que no aguanta es la forma en que casi todos los temas las consultan. Una ficha de juego no es un post: tiene plataforma, género, año, desarrolladora, distribuidora y media docena de campos más. La tentación es guardarlos como post meta y filtrar con meta_query. Funciona con cincuenta fichas y se cae con ochocientas.
El motivo es cómo está montada la tabla wp_postmeta: una fila por campo y por entrada, con un índice sobre meta_key pero no sobre el valor. Filtrar por «Amiga» obliga a MySQL a recorrer todas las filas de esa clave y a unirlas contra wp_posts. Cada filtro adicional es otro JOIN sobre la misma tabla. Tres filtros combinados y la consulta que debía tardar milisegundos tarda cientos.
Lo que sí está indexado de fábrica en WordPress son las taxonomías. Plataforma, género y década son taxonomías; el resto —año de salida, desarrolladora— se queda en meta porque se muestra, no se filtra. Esa sola decisión, tomada antes de escribir una línea de plantilla, es la diferencia entre un archivo que responde y uno que hay que rescatar a base de caché.
Las tres banderas que casi nadie pone
En un listado paginado, WP_Query hace por defecto tres cosas que no hacen falta:
- no_found_rows: sin él, WordPress cuenta todos los resultados con SQL_CALC_FOUND_ROWS solo para pintar «página 3 de 44». Si el paginador necesita el total, se cachea aparte y se refresca cuando entra una ficha nueva.
- update_post_meta_cache: precarga todo el post meta de las entradas del listado, aunque la tarjeta solo enseñe título, carátula y plataforma.
- update_post_term_cache: precarga los términos de todas las taxonomías. Si la tarjeta enseña la plataforma, se piden solo esos términos, no los seis vocabularios enteros.
Ninguna de las tres es un truco: son argumentos documentados de WP_Query. Están activados por defecto porque WordPress no sabe qué va a pintar la plantilla. Nosotros sí lo sabemos.
Una plantilla no debe pedir un dato que no va a pintar. Suena obvio, y es exactamente lo que hace un tema genérico en cada página de archivo.
Paginar de verdad, no cargar y esconder
Un archivo de 870 fichas se pagina. No se carga entero y se oculta con CSS, y no se pagina solo con scroll infinito. El scroll infinito rompe dos cosas a la vez: el rastreador de Google no dispara eventos de scroll, así que solo ve la primera tanda; y quien llega desde una búsqueda no puede enlazar lo que está viendo.
Aquí la paginación es la clásica, con URLs reales y rastreables, y con enlaces a la primera, la última y las vecinas para que ninguna ficha quede a más de tres clics de la portada. Sobre eso se puede añadir carga progresiva como comodidad, pero el esqueleto de abajo tiene que funcionar con JavaScript desactivado.
El peso está en las carátulas, no en el HTML
Una página de listado con 24 fichas es HTML barato y ancho de banda caro: 24 carátulas. Tres decisiones se llevan casi todo el ahorro.
- Un tamaño de imagen propio para la tarjeta, generado al subir con add_image_size, en vez de servir el original y dejar que lo reescale el navegador.
- loading=lazy en todo lo que está por debajo del pliegue y, muy importante, NO en la primera fila: la primera carátula suele ser el elemento LCP, y aplazarla es aplazar la métrica que mide Google.
- width y height explícitos en cada imagen. Sin ellos el navegador no reserva el hueco, las tarjetas saltan cuando cargan las carátulas, y eso es CLS puro.
Cloudflare va delante y cachea las páginas de archivo, que cambian poco: una ficha nueva a la semana no justifica ir a PHP en cada visita. La invalidación se dispara al publicar, no por tiempo, para que una ficha recién subida aparezca al momento.
La estética retro no puede pagarla el rendimiento
El sitio tiene CRT, píxeles y synthwave, y esa es media razón por la que la comunidad lo siente suyo. Pero los guiños viven en la superficie: tipografías, brillos y rejillas. La estructura, la jerarquía y la accesibilidad son las de cualquier sitio serio. Un barrido de CRT es un pseudoelemento con un degradado repetido, no un canvas animado. Un brillo de neón es un text-shadow, no una imagen.
Es fácil pasarse con lo retro y acabar con algo ilegible, y esa era la línea que no queríamos cruzar: el archivo es de la comunidad, y hay gente que lo consulta desde un móvil de hace cinco años.
Qué nos llevamos de aquí
Casi todos los problemas de rendimiento de un WordPress con mucho contenido no son de WordPress: vienen de haber modelado el contenido como si fuera un blog. Cuando plataforma y género son taxonomías, el listado pide solo lo que pinta y las imágenes traen sus dimensiones, un archivo de 870 fichas se comporta como uno de cincuenta.