- 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>
5.0 KiB
5.0 KiB
Tasks: Refactorizar AdSense Lazy Loading
Nota: Las tareas siguen el flujo de 5 fases del proyecto. Pasos adicionales (FieldMapper, Asset Enqueuer, JS) son subtareas de infraestructura.
FASE 1: Schema JSON
1.1 Actualizar adsense-placement.json
- Incrementar version de
1.4.0a1.5.0 - Agregar campo
lazy_loading_enabledal grupobehavior:"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)" } - Agregar campo
lazy_rootmarginal grupobehavior(tipo select, default "200") - Agregar campo
lazy_fill_timeoutal grupobehavior(tipo select, default "5000")
1.2 Sincronizar a BD
- Ejecutar
wp roi-theme sync-component adsense-placement - Verificar campos creados en BD con valores default
FASE 2: Renderer (BD → HTML + CSS)
2.1 Actualizar AdsensePlacementRenderer.php
- Leer
lazy_loading_enableddesde settings - Generar CSS dinamico via
CSSGeneratorService:if ($settings['lazy_loading_enabled']) { $this->cssGenerator->generate([ '.roi-ad-slot' => ['display' => 'none'], '.roi-ad-slot.roi-ad-filled' => ['display' => 'block'], '.roi-ad-slot.roi-ad-empty' => ['display' => 'none'], ]); } - Agregar
data-ad-lazy="true"al markup del slot si lazy enabled - Mantener compatibilidad con
lazy_loading_enabled: false
2.2 Actualizar enqueue-scripts.php (AssetEnqueuer)
- Leer settings de lazy loading desde BD
- Usar
wp_localize_script()para pasar config a JS: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, ]); - Remover cualquier configuracion hardcodeada existente
2.3 Actualizar AdsensePlacementFieldMapper.php
- Agregar
lazy_loading_enabledal array de mappings - Agregar
lazy_rootmarginal array de mappings - Agregar
lazy_fill_timeoutal array de mappings - Verificar tipos correctos (boolean, string, string → parseados en Enqueuer)
FASE 3: FormBuilder (UI Admin)
3.1 Actualizar AdsensePlacementFormBuilder.php
- Agregar seccion "Lazy Loading" dentro del grupo Exclusions/Forms
- Agregar toggle para
lazy_loading_enabled - Agregar select para
lazy_rootmargin(label: "Pre-carga (px)") - Agregar select para
lazy_fill_timeout(label: "Timeout fill (ms)") - Agregar nota indicando que cambios requieren vaciar cache
FASE 4: JavaScript (Infrastructure)
4.1 Backup
- Crear backup
adsense-loader.legacy.js
4.2 Refactorizar adsense-loader.js
- Refactorizar para leer config de
window.roiAdsenseConfig - Implementar deteccion de soporte Intersection Observer
- Implementar
observeAdSlots()con Intersection Observer - Implementar
activateAdSlot(slot)para activacion individual - Implementar MutationObserver para detectar contenido en
<ins> - Implementar
checkAdFill()con criterios concretos:- Verificar
data-ad-statusprimero - Fallback a verificar children (iframe, div[id])
- Verificar
- Implementar timeout por slot para marcar como vacio
- Implementar manejo de error de red con retry (2s delay, max 1 retry)
- Implementar fallback para navegadores sin soporte
- Mantener carga diferida de
adsbygoogle.js(primera activacion) - Mantener compatibilidad con
lazyEnabled: false(modo legacy)
FASE 5: Validacion
5.1 Validacion de Arquitectura
- Ejecutar
php Shared/Infrastructure/Scripts/validate-architecture.php adsense-placement - Verificar que no hay CSS estatico nuevo
- Verificar que config viene de BD, no hardcodeada
- Verificar que FieldMapper tiene todos los campos
5.2 Testing Local
- Probar con lazy_loading_enabled: true
- Verificar ads cargan al scroll (DevTools Network)
- Verificar slots vacios NO se muestran
- Probar con lazy_loading_enabled: false (modo legacy)
- Verificar fallback en navegador sin Intersection Observer
- Medir Core Web Vitals con Lighthouse (antes/despues)
POST-IMPLEMENTACION
Deploy
- Commit con mensaje descriptivo
- Deploy a produccion
- Ejecutar sync-component en produccion
- Vaciar cache (Redis, W3TC)
- Verificar funcionamiento en produccion
Monitoreo (24-48h)
- Monitorear fill rate en AdSense dashboard
- Verificar no hay errores en consola de usuarios
- Comparar Core Web Vitals antes/despues
Cleanup
- Remover
debug: truede adsense-loader.js (ya pendiente) - Remover debug de ContentAdInjector.php (ya pendiente)
- Remover
adsense-loader.legacy.jssi todo funciona (7+ dias) - Archivar esta especificacion en
openspec/archive/