El lazy loading (carga diferida) es una técnica de optimización web que retrasa la carga de recursos no visibles — imágenes, vídeos, componentes, datos — hasta el momento en que el usuario hace scroll hacia la zona de la página donde aparecen, reduciendo así el tiempo de carga inicial y el consumo de ancho de banda.
Aquí está la paradoja que pocos equipos quieren escuchar: el lazy loading es excelente para tus usuarios y terrible para tus tests visuales. Es una tecnología diseñada para no cargar contenido hasta que es visible. Pero una herramienta de test visual necesita ver el contenido para testearlo. Los dos objetivos están fundamentalmente en tensión.
Esta tensión no es una razón para elegir uno en detrimento del otro. Tu sitio necesita lazy loading para rendir — los datos de Google son claros, el tiempo de carga es un factor de posicionamiento SEO y un determinante mayor de la tasa de rebote. Y tu sitio necesita tests visuales para garantizar que el lazy loading no introduce regresiones — un placeholder que nunca desaparece, una imagen que se carga con las dimensiones equivocadas, un layout que salta cuando aparece el contenido.
Este artículo te explica cómo conciliar ambos.
Por qué el lazy loading complica el test visual
El contenido invisible no se puede testear
El principio fundamental del lazy loading es que el contenido situado por debajo de la línea de flotación (below the fold) no se carga en la carga inicial de la página. Un screenshot tomado inmediatamente después de la carga solo muestra el contenido por encima de la línea de flotación — todo lo demás está ausente o reemplazado por placeholders.
Es un problema de cobertura. Si tu página mide 5.000 píxeles de alto y tu viewport mide 900 píxeles, un screenshot inicial cubre solo el 18% de tu página. El 82% restante no se testea. En una página de producto e-commerce, esto significa que la descripción, las opiniones de clientes, los productos recomendados y el footer nunca se verifican visualmente.
Algunos equipos creen resolver el problema tomando un screenshot full-page. Pero un screenshot full-page no activa el lazy loading — captura la página tal como está renderizada en el momento de la captura, con los placeholders y los elementos no cargados. Obtienes una imagen completa de una página incompleta.
El momento de la captura: un dilema permanente
¿Cuándo exactamente debes tomar tu screenshot? La pregunta parece simple. No lo es.
Si tomas el screenshot inmediatamente después de la carga de la página, capturas el estado inicial con los placeholders. Es rápido pero incompleto. Si haces scroll hasta el final de la página antes de capturar, activas la carga de todo el contenido diferido — pero para cuando cada recurso se carga, el contenido de la parte superior de la página puede haber cambiado (animaciones, actualizaciones en tiempo real, reexhibición del header).
Y además, el propio scroll modifica la apariencia de la página. Un header sticky que aparece al hacer scroll, un botón "volver arriba" que se materializa, un indicador de progreso de lectura que se llena — todos estos elementos cambian según la posición de scroll, y su estado en el momento de la captura varía de una ejecución a otra.
Los placeholders de imagen y el layout shift
El lazy loading de imágenes utiliza placeholders para reservar espacio en el layout: rectángulos grises, desenfocados de baja resolución (LQIP — Low Quality Image Placeholder), SVGs coloreados, o simplemente nada. Cuando la imagen real se carga, reemplaza al placeholder.
El problema surge cuando el reemplazo del placeholder por la imagen modifica las dimensiones del elemento. Es el famoso Cumulative Layout Shift (CLS) — un desplazamiento visible que mueve los elementos circundantes. Si tu screenshot se toma durante este desplazamiento, capturas un estado transitorio que no es ni el placeholder ni el estado final.
Las buenas prácticas web recomiendan definir dimensiones explícitas en las imágenes (width y height en HTML) para evitar el layout shift. Pero no todos los equipos siguen estas buenas prácticas, y las imágenes responsive con dimensiones variables hacen la cosa más compleja.
El infinite scroll: una página sin fin
El infinite scroll lleva el problema del lazy loading al extremo. En lugar de una página de tamaño fijo con contenido diferido, tienes una página cuya longitud es potencialmente infinita. Cada scroll hacia abajo carga nuevos elementos y alarga la página.
¿Cómo testeas visualmente una página sin fin? No puedes capturar un screenshot full-page — la página no tiene "full". Debes decidir arbitrariamente cuándo dejar de hacer scroll, cuántos elementos constituyen una muestra suficiente, y cómo gestionar el hecho de que el contenido cargado por el infinite scroll suele alimentarse de datos que cambian (nuevos artículos, nuevas publicaciones, nuevos productos).
El infinite scroll también crea un problema de memoria. Cada lote de contenido cargado añade elementos al DOM. Después de suficientes scrolls, el navegador puede ralentizarse, el renderizado puede volverse menos fluido, y el timing de las operaciones puede variar — introduciendo no-determinismo en tus tests.
Las estrategias para testear visualmente el contenido en lazy loading
Estrategia 1: el scroll incremental con capturas múltiples
En lugar de buscar un screenshot único de toda la página, divide la página en segmentos y captura cada segmento por separado. Haz scroll de la altura de un viewport, espera a que se cargue el contenido diferido, captura un screenshot, y continúa.
Este enfoque produce una serie de screenshots — viewport 1, viewport 2, viewport 3, etc. — que comparas individualmente con sus baselines respectivas. Cada screenshot cubre un segmento específico de la página con todo el contenido cargado.
La ventaja es que obtienes cobertura completa con contenido totalmente cargado. La desventaja es la multiplicidad de baselines a mantener y la gestión del timing entre cada scroll y cada captura. El tiempo de estabilización después del scroll — el tiempo para que las imágenes se carguen, las animaciones de transición se completen, el layout se estabilice — debe ser suficiente pero no excesivo.
Para el infinite scroll, define un número fijo de scrolls (por ejemplo 5 o 10) y testea los segmentos correspondientes. No puedes testear el infinito, pero puedes testear una muestra representativa.
Estrategia 2: forzar la carga completa antes de la captura
Algunas herramientas permiten desactivar el lazy loading en el entorno de test. El atributo HTML loading="eager" fuerza la carga inmediata de todas las imágenes. Los scripts Intersection Observer pueden parchearse para considerar que todos los elementos son visibles inmediatamente. Los frameworks como React y Vue que implementan lazy loading a nivel de componente pueden configurarse para cargar todos los componentes en modo test.
Este enfoque transforma tu página con lazy loading en una página completamente cargada, y puedes capturar un screenshot full-page clásico. Es simple, directo, y resuelve el problema de cobertura.
Pero ya no estás testeando el lazy loading en sí. Si tu implementación de lazy loading tiene un bug — un componente que nunca se carga, un placeholder que se queda visible, una animación de transición que rompe el layout — no lo verás en modo "eager". Estás testeando el contenido, no el mecanismo de carga.
Es un compromiso aceptable si tu objetivo es únicamente detectar regresiones visuales en el diseño. Si también quieres verificar que el lazy loading funciona correctamente, necesitas la siguiente estrategia.
Estrategia 3: testear los estados de transición
En lugar de sortear el lazy loading, testéalo explícitamente. Captura screenshots en cada etapa del ciclo de carga: el estado inicial con los placeholders, el estado durante la carga (transición), y el estado final con el contenido completo.
Cada estado tiene su propia baseline. El test del estado inicial verifica que los placeholders están correctamente dimensionados y posicionados. El test del estado final verifica que el contenido cargado reemplaza correctamente los placeholders sin romper el layout. El test de transición verifica que no hay layout shift excesivo.
Este enfoque es el más completo pero también el más pesado de mantener. Tres baselines por componente con lazy loading son tres veces más mantenimiento cuando el diseño evoluciona. Resérvalo para los componentes críticos donde el comportamiento del lazy loading es esencial para la experiencia de usuario.
Estrategia 4: la comparación estructural, indiferente al contenido de píxeles
El enfoque estructural resuelve elegantemente varios problemas del lazy loading simultáneamente. En vez de comparar los píxeles de un placeholder y los píxeles de la imagen final, compara la estructura del elemento: su posición en el DOM, sus dimensiones calculadas, sus propiedades CSS, su visibilidad.
Un placeholder correctamente dimensionado ocupa el mismo espacio que la imagen final — la estructura es idéntica aunque los píxeles sean completamente diferentes. Un componente con lazy loading que se carga correctamente mantiene la misma posición y las mismas dimensiones que su placeholder. El enfoque estructural valida esta equivalencia sin preocuparse por el contenido de píxeles de las imágenes.
Es el enfoque que Delta-QA usa nativamente. Cuando un placeholder de 400x300 píxeles es reemplazado por una imagen de 400x300 píxeles, la estructura no cambia — no hay alerta. Cuando un placeholder de 400x300 es reemplazado por una imagen de 400x200 (un bug en la relación de aspecto), la estructura cambia — alerta legítima.
Los desafíos específicos del infinite scroll
El infinite scroll merece atención particular porque combina los problemas del lazy loading con desafíos propios.
El problema de la repetibilidad
El infinite scroll generalmente carga contenido paginado desde una API. El contenido de la página 2 depende de lo que está en la página 1. Si el conjunto de datos cambia entre dos ejecuciones de test (un nuevo artículo publicado, un producto retirado), las páginas no tienen el mismo contenido, y la comparación falla.
Para obtener resultados repetibles, debes congelar los datos subyacentes. Usa una API mockeada que siempre devuelva los mismos datos en el mismo orden, o testea contra un entorno de staging con un conjunto de datos fijo.
El problema del renderizado de márgenes y la agrupación
Las listas con infinite scroll a menudo muestran contenido con cabeceras de agrupación — "Hoy", "Ayer", "La semana pasada". Estas cabeceras dependen de la fecha actual y cambian de un día a otro. Un artículo publicado "hoy" estará bajo la cabecera "Ayer" mañana.
La solución es la misma que para cualquier contenido temporal: congela la fecha del sistema en el entorno de test.
El problema del rendimiento degradado
Después de 20 o 30 scrolls sucesivos, el rendimiento del navegador puede degradarse por el número de elementos en el DOM. Esta degradación afecta al timing del renderizado y puede introducir no-determinismo en tus screenshots.
Las aplicaciones bien diseñadas implementan virtualización — solo mantienen en el DOM los elementos actualmente visibles, reciclando nodos DOM a medida que el usuario hace scroll. Si tu aplicación virtualiza el DOM, el número de elementos se mantiene constante sin importar el número de scrolls, y el rendimiento permanece estable.
Si tu aplicación no usa virtualización, limita el número de scrolls en tus tests para permanecer en la zona de rendimiento aceptable.
Recomendaciones prácticas para integrar el lazy loading en tu estrategia de test visual
Para las imágenes con lazy loading, lo mínimo es testear el estado final — el estado donde todas las imágenes visibles en el viewport están cargadas. Usa el scroll incremental para activar la carga, espera la estabilización, y captura. Define expectativas claras: todas las imágenes del viewport deben estar cargadas (sin placeholders visibles), y ningún layout shift debe producirse después de la carga.
Para los componentes con lazy loading (code splitting, dynamic imports), testea en dos modos: el modo "todo cargado" para verificar el renderizado de los componentes, y el modo "carga natural" para verificar los estados de transición y los fallbacks.
Para el infinite scroll, define un perímetro de test realista. Testea las 3 a 5 primeras cargas (scrolls), lo que cubre el comportamiento inicial, la lógica de paginación, y la transición entre lotes. No intentes testear la totalidad del flujo — no es práctico ni necesario.
Para los placeholders, testéalos explícitamente. Los placeholders forman parte de la experiencia de usuario — un placeholder mal dimensionado causa layout shift, un placeholder ausente deja un hueco blanco en la página. Captura un screenshot del estado inicial (antes del scroll) y verifica que los placeholders están correctamente dimensionados y posicionados.
Para el timing, prefiere las esperas condicionales a los retardos fijos. Espera a que las imágenes estén cargadas (vía el evento load en los elementos img) en vez de esperar un número arbitrario de segundos. Los retardos fijos son frágiles — 2 segundos pueden bastar en local y ser insuficientes en CI bajo carga.
El lazy loading es un aliado, no un enemigo
El lazy loading optimiza el rendimiento de tu sitio. Reduce el tiempo de carga inicial, el consumo de ancho de banda y el uso de recursos del lado del cliente. Son beneficios reales y medibles para tus usuarios.
El hecho de que complique el test visual no es una razón para abandonarlo — es una razón para adaptar tu estrategia de test. Y las herramientas modernas de test visual, Delta-QA a la cabeza, están diseñadas para gestionar esta complejidad sin que tengas que elegir entre rendimiento y testeabilidad.
El lazy loading no es un obstáculo para el test visual. Es una restricción técnica con soluciones técnicas. Impleméntalas, y tendrás lo mejor de ambos mundos: páginas rápidas y tests fiables.
FAQ
¿El lazy loading hace imposible el test visual full-page?
No, pero requiere un enfoque diferente del screenshot full-page clásico. O fuerzas la carga completa (loading="eager") antes de la captura, o haces scroll progresivamente capturando cada segmento por separado. Ambos enfoques ofrecen cobertura completa — el primero es más simple, el segundo es más fiel al comportamiento real de la página.
¿Cómo testear visualmente una página con infinite scroll?
Define un perímetro de test realista: 3 a 5 scrolls cubren el comportamiento inicial, la lógica de paginación, y las transiciones entre lotes. Usa datos mockeados para garantizar la repetibilidad. Captura cada segmento como un screenshot independiente con su propia baseline. No intentes testear el infinito — testea una muestra representativa y fiable.
¿Hay que desactivar el lazy loading en el entorno de test?
Depende de tu objetivo. Si testeas el contenido (detectar regresiones visuales en el diseño), desactiva el lazy loading para simplificar las capturas. Si testeas el mecanismo de carga (verificar que los placeholders, las transiciones y la carga diferida funcionan), mantén el lazy loading activado y testea explícitamente los diferentes estados.
¿Cómo gestionar el layout shift causado por la carga diferida de imágenes?
Define siempre dimensiones explícitas (width y height) en tus imágenes para reservar espacio en el layout. Usa placeholders del mismo tamaño que la imagen final (LQIP o rectángulos coloreados). Testea visualmente el estado inicial (con placeholders) y el estado final (con imágenes) para verificar que las dimensiones no cambian y que no se produce ningún desplazamiento.
¿Los tests visuales con lazy loading son más lentos que los tests clásicos?
Sí, necesariamente. El scroll incremental con esperas de carga en cada paso toma más tiempo que una captura instantánea de una página completamente cargada. Es el coste de la cobertura completa. Optimiza paralelizando tus tests, limitando el número de scrolls al estricto necesario, y usando esperas condicionales en vez de retardos fijos para minimizar el tiempo de espera.
¿Delta-QA gestiona el lazy loading y el infinite scroll?
Sí. El enfoque estructural de Delta-QA es particularmente adecuado para el lazy loading porque compara la estructura en vez de los píxeles. Un placeholder correctamente dimensionado y la imagen final tienen la misma estructura — sin falso positivo. La herramienta gestiona el scroll incremental, las esperas de carga, y la comparación por segmentos, todo sin escribir una línea de código.
Para profundizar
- Test Visual para Ruby on Rails: Por Qué las View Specs No Son Suficientes y Cómo el Test Visual Llena el Vacío
- Bugs Visuales y SEO: Cómo el CLS Destruye Tu Posicionamiento en Google (y Cómo el Test Visual lo Previene)
- Test Visual en Laravel Blade: El Front-End Que los Desarrolladores Back-End Olvidan Testear
- Test Visual Shift-Right: Por Qué el Test Visual No Se Detiene en el Despliegue
El lazy loading optimiza el rendimiento de tu sitio. Delta-QA se asegura de que no introduce regresiones visuales. Los dos no son incompatibles — son complementarios. Testea tus páginas dinámicas con el mismo rigor que tus páginas estáticas.