Files
roi-theme/openspec/changes/refactor-adsense-lazy-loading/schema-changes.md
FrankZamora 179a83e9cd feat(js): implement intersection observer lazy loading for adsense
- Add per-slot lazy loading with Intersection Observer API
- Implement fill detection via MutationObserver and data-ad-status
- Add configurable rootMargin and fillTimeout from database
- Generate dynamic CSS based on lazy_loading_enabled setting
- Add legacy mode fallback for browsers without IO support
- Include backup of previous implementation (adsense-loader.legacy.js)
- Add OpenSpec documentation with test plan (72 tests verified)

Schema changes:
- Add lazy_loading_enabled (boolean, default: true)
- Add lazy_rootmargin (select: 0-500px, default: 200)
- Add lazy_fill_timeout (select: 3000-10000ms, default: 5000)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 15:48:20 -06:00

3.3 KiB

Cambios al Schema: adsense-placement.json

Resumen

Agregar 3 campos nuevos al grupo behavior para configurar el lazy loading de anuncios.

Nota: Los campos van en grupo behavior (priority 70) porque configuran el comportamiento del componente, no formularios de exclusion.

Campos a Agregar

Ubicacion: groups.behavior.fields

Campo 1: lazy_loading_enabled

"lazy_loading_enabled": {
  "type": "boolean",
  "label": "Lazy Loading de Anuncios",
  "default": true,
  "editable": true,
  "description": "Cargar anuncios individualmente al entrar al viewport (mejora fill rate)"
}

Campo 2: lazy_rootmargin

"lazy_rootmargin": {
  "type": "select",
  "label": "Pre-carga (px antes del viewport)",
  "default": "200",
  "editable": true,
  "options": {
    "0": "0px (sin pre-carga)",
    "100": "100px",
    "200": "200px (recomendado)",
    "300": "300px",
    "400": "400px",
    "500": "500px"
  },
  "description": "Pixeles de anticipacion para iniciar carga de anuncio"
}

Nota: Tipo select en lugar de number porque el schema solo soporta: boolean, text, textarea, url, select, color.

Campo 3: lazy_fill_timeout

"lazy_fill_timeout": {
  "type": "select",
  "label": "Timeout de llenado (ms)",
  "default": "5000",
  "editable": true,
  "options": {
    "3000": "3 segundos",
    "5000": "5 segundos (recomendado)",
    "7000": "7 segundos",
    "10000": "10 segundos"
  },
  "description": "Tiempo maximo para esperar contenido de Google antes de ocultar slot"
}

Comando de Sincronizacion

Despues de actualizar el JSON:

wp roi-theme sync-component adsense-placement

Version del Schema

Incrementar version de 1.4.0 a 1.5.0 para reflejar nueva funcionalidad.

Relacion con delay_enabled

El campo delay_enabled (en grupo forms) controla si la biblioteca adsbygoogle.js se carga con retraso.

El campo lazy_loading_enabled (en grupo behavior) controla si los slots individuales se activan por visibilidad.

Ambos pueden estar activos simultaneamente - son complementarios:

  • delay_enabled: true = biblioteca no se carga hasta interaccion/timeout
  • lazy_loading_enabled: true = slots se activan individualmente por viewport

Si lazy_loading_enabled: false, el sistema usa el comportamiento actual (cargar todos los ads de una vez despues de que la biblioteca cargue).

Interaccion con Cache

Importante: El CSS dinamico generado por CSSGeneratorService incluye display: none para .roi-ad-slot cuando lazy loading esta habilitado.

Si se cambia lazy_loading_enabled de true a false:

  1. El CSS dinamico cambiara en el siguiente render
  2. Se DEBE vaciar cache (Redis, W3TC, OPcache) para que el cambio surta efecto
  3. Usuarios con HTML cacheado veran slots ocultos hasta que su cache expire

Recomendacion: Agregar nota en FormBuilder indicando que cambios requieren vaciar cache.

Parseo de Valores en PHP

Como los campos son tipo select con valores string, el AdsenseAssetEnqueuer debe parsear:

wp_localize_script('adsense-loader', 'roiAdsenseConfig', [
    'lazyEnabled' => (bool) $settings['lazy_loading_enabled'],
    'rootMargin' => (int) $settings['lazy_rootmargin'] . 'px 0px',
    'fillTimeout' => (int) $settings['lazy_fill_timeout'],
    'debug' => WP_DEBUG,
]);