feat(js): switch to eager loading to eliminate layout shift

Instead of lazy loading slots when they enter the viewport (which
causes layout shift when unfilled slots collapse), now all slots
are activated immediately on page load.

- Slots start collapsed (max-height:0, opacity:0) via CSS
- All slots are activated with 100ms stagger to avoid rate limiting
- Only slots confirmed as 'filled' expand and become visible
- Unfilled slots remain collapsed - zero layout shift

This completely eliminates the CLS issue where content would jump
when ad slots were hidden after entering the viewport.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-12-10 17:11:08 -06:00
parent a4f63145dd
commit 5971f2c971
2 changed files with 33 additions and 13 deletions

View File

@@ -593,6 +593,27 @@
});
}
// =========================================================================
// EAGER LOADING (ACTIVACION INMEDIATA)
// =========================================================================
/**
* Activa todos los slots inmediatamente sin esperar viewport.
* Los slots inician colapsados (CSS) y solo se expanden si reciben anuncio.
* Esto evita layout shift porque el usuario nunca ve espacios vacios.
*/
function activateAllSlotsEagerly() {
var slots = document.querySelectorAll('.roi-ad-slot[data-ad-lazy="true"]');
debugLog('Activando ' + slots.length + ' slots de manera eager');
slots.forEach(function(slot, index) {
// Pequeño delay escalonado para no saturar AdSense
setTimeout(function() {
activateSlot(slot);
}, index * 100); // 100ms entre cada slot
});
}
// =========================================================================
// INICIALIZACION
// =========================================================================
@@ -611,8 +632,8 @@
return;
}
debugLog('Inicializando AdSense Lazy Loader v2.0');
debugLog('Config: lazyEnabled=' + CONFIG.lazyEnabled + ', rootMargin=' + CONFIG.rootMargin + ', fillTimeout=' + CONFIG.fillTimeout);
debugLog('Inicializando AdSense Lazy Loader v2.1 (Eager Mode)');
debugLog('Config: lazyEnabled=' + CONFIG.lazyEnabled + ', fillTimeout=' + CONFIG.fillTimeout);
// Decidir modo de operacion
if (!CONFIG.lazyEnabled) {
@@ -621,21 +642,20 @@
return;
}
// Intentar inicializar Intersection Observer
var observerInitialized = initIntersectionObserver();
if (!observerInitialized) {
// Fallback a modo legacy
initLegacyMode();
return;
}
// NUEVA ESTRATEGIA: Eager loading
// En lugar de esperar a que los slots entren al viewport (lo cual causa
// layout shift cuando se ocultan slots vacios), activamos todos los slots
// inmediatamente. Los slots inician colapsados via CSS y solo se expanden
// cuando AdSense confirma que tienen anuncio (filled).
// Esto elimina completamente el layout shift.
debugLog('Usando modo eager: activar todos los slots inmediatamente');
// Esperar a que el DOM este listo
if (document.readyState === 'interactive' || document.readyState === 'complete') {
observeAllSlots();
activateAllSlotsEagerly();
} else {
document.addEventListener('DOMContentLoaded', function() {
observeAllSlots();
activateAllSlotsEagerly();
});
}
}

View File

@@ -18,7 +18,7 @@ if (!defined('ABSPATH')) {
}
// Definir constante de versión del tema
define('ROI_VERSION', '1.0.25');
define('ROI_VERSION', '1.0.26');
// =============================================================================
// 1. CARGAR AUTOLOADER MANUAL