perf(js): use fast polling for fill detection

Replace MutationObserver with 50ms polling strategy.
AdSense sets data-ad-status very quickly after iframe,
but MutationObserver sometimes has delays.

Max polling: 3s (60 attempts * 50ms)

🤖 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 16:52:06 -06:00
parent ffc22a21ea
commit 88103a774b
2 changed files with 40 additions and 28 deletions

View File

@@ -258,6 +258,15 @@
// DETECCION DE LLENADO // DETECCION DE LLENADO
// ========================================================================= // =========================================================================
/** @type {Map<Element, number>} */
var pollIntervals = new Map();
/** Intervalo de polling rapido en ms */
var POLL_INTERVAL = 50;
/** Maximo de intentos de polling (50ms * 60 = 3 segundos max) */
var MAX_POLL_ATTEMPTS = 60;
/** /**
* Inicia la deteccion de llenado para un slot * Inicia la deteccion de llenado para un slot
* @param {Element} slot * @param {Element} slot
@@ -269,33 +278,30 @@
return; return;
} }
// Configurar timeout // Estrategia: Polling rapido (50ms) para detectar data-ad-status lo antes posible.
var timeoutId = setTimeout(function() { // AdSense establece data-ad-status muy rapido despues de inyectar el iframe,
debugLog('Timeout de llenado alcanzado'); // pero MutationObserver a veces no lo detecta inmediatamente.
markSlotEmpty(slot); var pollCount = 0;
}, CONFIG.fillTimeout); var pollId = setInterval(function() {
fillTimeouts.set(slot, timeoutId); pollCount++;
// Configurar MutationObserver si hay soporte
if (hasMutationObserverSupport()) {
var mutationObserver = new MutationObserver(function(mutations) {
if (checkFillStatus(slot, ins)) { if (checkFillStatus(slot, ins)) {
// Ya procesado en checkFillStatus // Estado detectado, limpiar polling
clearInterval(pollId);
pollIntervals.delete(slot);
return;
} }
});
mutationObserver.observe(ins, { // Si alcanzamos el maximo de intentos, marcar como vacio
attributes: true, if (pollCount >= MAX_POLL_ATTEMPTS) {
childList: true, debugLog('Polling timeout alcanzado (' + (pollCount * POLL_INTERVAL) + 'ms)');
subtree: true, clearInterval(pollId);
attributeFilter: ['data-ad-status'] pollIntervals.delete(slot);
}); markSlotEmpty(slot);
fillObservers.set(slot, mutationObserver);
} else {
// Sin MutationObserver, solo usar timeout
debugLog('Sin soporte MutationObserver, usando solo timeout');
} }
}, POLL_INTERVAL);
pollIntervals.set(slot, pollId);
} }
/** /**
@@ -353,17 +359,23 @@
} }
/** /**
* Limpia observadores y timeouts de un slot * Limpia observadores, timeouts e intervalos de un slot
* @param {Element} slot * @param {Element} slot
*/ */
function cleanupSlot(slot) { function cleanupSlot(slot) {
// Limpiar timeout // Limpiar polling interval
if (pollIntervals.has(slot)) {
clearInterval(pollIntervals.get(slot));
pollIntervals.delete(slot);
}
// Limpiar timeout (legacy)
if (fillTimeouts.has(slot)) { if (fillTimeouts.has(slot)) {
clearTimeout(fillTimeouts.get(slot)); clearTimeout(fillTimeouts.get(slot));
fillTimeouts.delete(slot); fillTimeouts.delete(slot);
} }
// Limpiar MutationObserver // Limpiar MutationObserver (legacy)
if (fillObservers.has(slot)) { if (fillObservers.has(slot)) {
fillObservers.get(slot).disconnect(); fillObservers.get(slot).disconnect();
fillObservers.delete(slot); fillObservers.delete(slot);

View File

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