perf(TBT): Fase 2.3 - Eliminar código JS muerto (-96%)

Diagnóstico:
- main.js: ~95% código muerto (IDs no coinciden con DOM)
- header.js: ~90% código muerto (usa Bootstrap, no custom menu)

Cambios:
- main.js: 315 → 25 líneas (solo navbar scroll effect)
- header.js: DESHABILITADO completamente (343 líneas)
- Reducción total: ~633 líneas de JS innecesario

Impacto esperado: TBT -50-100ms

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-11-27 12:59:19 -06:00
parent 7e13678e0b
commit b0def25348
2 changed files with 43 additions and 342 deletions

View File

@@ -1,8 +1,20 @@
/**
* ROI THEME - MAIN JAVASCRIPT
*
* OPTIMIZACIÓN TBT Fase 2.3 (2025-11-27):
* - Eliminado ~300 líneas de código muerto
* - Removido: loadContactModal (modalContainer no existe)
* - Removido: initContactForm (contactForm no existe)
* - Removido: footerContactForm handler (ID incorrecto)
* - Removido: TOC ScrollSpy duplicado (.toc-container no existe)
* - Removido: smooth scroll duplicado (Bootstrap lo maneja)
* - Removido: console.log de debug
*
* Código activo: Solo efecto scroll del navbar
* Reducción: ~315 líneas → ~25 líneas
*/
// Navbar scroll effect
// Navbar scroll effect - adds 'scrolled' class when user scrolls
window.addEventListener('scroll', function() {
const navbar = document.querySelector('.navbar');
if (navbar) {
@@ -13,304 +25,3 @@ window.addEventListener('scroll', function() {
}
}
});
/**
* TOC (Table of Contents) - Handled by toc.js
* No duplicate code needed here - toc.js provides:
* - ScrollSpy with IntersectionObserver
* - Smooth scroll with prefers-reduced-motion support
* - Toggle functionality
* - localStorage state
*/
/**
* CTA A/B Testing
* Handled by cta-ab-testing.php (PHP) and cta-tracking.js
* - PHP renders only ONE variant based on cookie
* - cta-tracking.js handles Analytics tracking
*/
// Contact Modal - Dynamic Loading
function loadContactModal() {
const modalContainer = document.getElementById('modalContainer');
if (!modalContainer) return;
// Use theme URL from localized script
const modalUrl = (typeof roiheme !== 'undefined' && rroieme.themeUrl)
? roiheme.themeUrl + '/modal-contact.html'
: '/wp-content/themes/roitheme/modal-contact.html';
fetch(modalUrl)
.then(response => response.text())
.then(html => {
modalContainer.innerHTML = html;
initContactForm();
})
.catch(error => {
console.error('Error loading modal:', error);
});
}
document.addEventListener('DOMContentLoaded', loadContactModal);
// Contact Form - Webhook Submission
function initContactForm() {
const form = document.getElementById('contactForm');
if (!form) return;
form.addEventListener('submit', function(e) {
e.preventDefault();
const WEBHOOK_URL = 'https://tu-webhook.com/contacto';
const formData = {
fullName: document.getElementById('fullName').value,
company: document.getElementById('company').value,
whatsapp: document.getElementById('whatsapp').value,
email: document.getElementById('email').value,
comments: document.getElementById('comments').value,
timestamp: new Date().toISOString(),
source: 'APU Website - Modal'
};
if (!formData.fullName || !formData.whatsapp || !formData.email) {
showFormMessage('Por favor completa todos los campos requeridos', 'danger');
return;
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(formData.email)) {
showFormMessage('Por favor ingresa un correo electrónico válido', 'danger');
return;
}
const submitButton = form.querySelector('button[type="submit"]');
const originalText = submitButton.innerHTML;
submitButton.disabled = true;
submitButton.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Enviando...';
fetch(WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
})
.then(response => {
if (!response.ok) throw new Error('Error en el envío');
return response.json();
})
.then(data => {
showFormMessage('¡Mensaje enviado exitosamente!', 'success');
form.reset();
if (typeof gtag !== 'undefined') {
gtag('event', 'form_submission', {
'event_category': 'Contact Form',
'event_label': 'Form Submitted'
});
}
setTimeout(() => {
const modal = bootstrap.Modal.getInstance(document.getElementById('contactModal'));
if (modal) modal.hide();
}, 2000);
})
.catch(error => {
showFormMessage('Error al enviar el mensaje', 'danger');
})
.finally(() => {
submitButton.disabled = false;
submitButton.innerHTML = originalText;
});
});
}
function showFormMessage(message, type) {
const messageDiv = document.getElementById('formMessage');
if (!messageDiv) return;
messageDiv.textContent = message;
messageDiv.className = `mt-3 alert alert-${type}`;
messageDiv.style.display = 'block';
setTimeout(() => {
messageDiv.style.display = 'none';
}, 5000);
}
// Footer Contact Form
document.addEventListener('DOMContentLoaded', function() {
const footerForm = document.getElementById('footerContactForm');
if (!footerForm) return;
footerForm.addEventListener('submit', function(e) {
e.preventDefault();
const WEBHOOK_URL = 'https://tu-webhook.com/contacto';
const formData = {
fullName: document.getElementById('footerFullName').value,
company: document.getElementById('footerCompany').value,
whatsapp: document.getElementById('footerWhatsapp').value,
email: document.getElementById('footerEmail').value,
comments: document.getElementById('footerComments').value,
timestamp: new Date().toISOString(),
source: 'APU Website - Footer'
};
if (!formData.fullName || !formData.whatsapp || !formData.email) {
showFooterFormMessage('Por favor completa todos los campos requeridos', 'danger');
return;
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(formData.email)) {
showFooterFormMessage('Por favor ingresa un correo válido', 'danger');
return;
}
const submitButton = footerForm.querySelector('button[type="submit"]');
const originalText = submitButton.innerHTML;
submitButton.disabled = true;
submitButton.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Enviando...';
fetch(WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
})
.then(response => {
if (!response.ok) throw new Error('Error en el envío');
return response.json();
})
.then(data => {
showFooterFormMessage('¡Mensaje enviado exitosamente!', 'success');
footerForm.reset();
if (typeof gtag !== 'undefined') {
gtag('event', 'form_submission', {
'event_category': 'Footer Form',
'event_label': 'Form Submitted'
});
}
})
.catch(error => {
showFooterFormMessage('Error al enviar el mensaje', 'danger');
})
.finally(() => {
submitButton.disabled = false;
submitButton.innerHTML = originalText;
});
});
});
function showFooterFormMessage(message, type) {
const messageDiv = document.getElementById('footerFormMessage');
if (!messageDiv) return;
messageDiv.textContent = message;
messageDiv.className = `col-12 mt-2 alert alert-${type}`;
messageDiv.style.display = 'block';
setTimeout(() => {
messageDiv.style.display = 'none';
}, 5000);
}
// Smooth scroll for all anchor links
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
const href = this.getAttribute('href');
if (href === '#' || this.getAttribute('data-bs-toggle') === 'modal') {
return;
}
const targetElement = document.querySelector(href);
if (!targetElement) return;
e.preventDefault();
const navbar = document.querySelector('.navbar');
const navbarHeight = navbar ? navbar.offsetHeight : 0;
const offsetTop = targetElement.offsetTop - navbarHeight - 20;
window.scrollTo({
top: offsetTop,
behavior: 'smooth'
});
});
});
});
console.log('%c APU México ', 'background: #1e3a5f; color: #FF8600; font-size: 16px; font-weight: bold; padding: 10px;');
// === SIDEBAR TOC - ScrollSpy ===
// Table of Contents - ScrollSpy
function updateActiveSection() {
const tocLinks = document.querySelectorAll('.toc-container a');
if (!tocLinks.length) return;
const navbar = document.querySelector('.navbar');
const navbarHeight = navbar ? navbar.offsetHeight : 0;
const sectionIds = Array.from(tocLinks).map(link => {
const href = link.getAttribute('href');
return href ? href.substring(1) : null;
}).filter(id => id !== null);
const sections = sectionIds.map(id => document.getElementById(id)).filter(el => el !== null);
const scrollPosition = window.scrollY + navbarHeight + 100;
let activeSection = null;
for (let i = 0; i < sections.length; i++) {
const section = sections[i];
const sectionTop = section.offsetTop;
if (scrollPosition >= sectionTop) {
activeSection = section.getAttribute('id');
} else {
break;
}
}
tocLinks.forEach(link => {
link.classList.remove('active');
const href = link.getAttribute('href');
if (href === '#' + activeSection) {
link.classList.add('active');
}
});
}
// Smooth scroll for TOC links
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.toc-container a').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const targetId = this.getAttribute('href');
const targetElement = document.querySelector(targetId);
if (targetElement) {
const navbar = document.querySelector('.navbar');
const navbarHeight = navbar ? navbar.offsetHeight : 0;
const offsetTop = targetElement.offsetTop - navbarHeight - 40;
window.scrollTo({
top: offsetTop,
behavior: 'smooth'
});
}
});
});
updateActiveSection();
});
window.addEventListener('scroll', updateActiveSection);
// NOTE: Navbar dropdown parent links now work natively
// The PHP walker only adds data-bs-toggle="dropdown" for items without real URLs
// CSS hover handles showing dropdowns on desktop

View File

@@ -195,22 +195,28 @@ add_action('wp_enqueue_scripts', 'roi_enqueue_global_components', 7);
*
* NOTA: CSS del header se genera dinámicamente desde NavbarRenderer
* @see Public/Navbar/Infrastructure/Ui/NavbarRenderer.php
*
* DESHABILITADO: header.js (2025-11-27 - Optimización TBT Fase 2.3)
* Motivo: ~90% código muerto. Los elementos que busca no existen:
* - mobile-menu-toggle: no existe (sitio usa .navbar-toggler de Bootstrap)
* - mobile-menu: no existe (usa Bootstrap collapse)
* - masthead: no existe
* - Smooth scroll duplicado de main.js
* Reducción: ~343 líneas de JS eliminadas del parsing
*/
function roi_enqueue_header() {
// Header JS - with defer strategy
wp_enqueue_script(
'roi-header-js',
get_template_directory_uri() . '/Assets/js/header.js',
array(),
'1.0.0',
array(
'in_footer' => true,
'strategy' => 'defer',
)
);
}
add_action('wp_enqueue_scripts', 'roi_enqueue_header', 10);
// function roi_enqueue_header() {
// wp_enqueue_script(
// 'roi-header-js',
// get_template_directory_uri() . '/Assets/js/header.js',
// array(),
// '1.0.0',
// array(
// 'in_footer' => true,
// 'strategy' => 'defer',
// )
// );
// }
// add_action('wp_enqueue_scripts', 'roi_enqueue_header', 10);
/**
* Enqueue generic tables styles
@@ -268,42 +274,26 @@ add_action('wp_enqueue_scripts', 'roi_enqueue_video_styles', 11);
* Código único movido a: generic-tables.css, video.css
*/
function roi_enqueue_main_javascript() {
// Main JavaScript - navbar scroll effects and interactions
// Main JavaScript - navbar scroll effects
// OPTIMIZACIÓN TBT Fase 2.3: Eliminado ~300 líneas de código muerto
// Solo mantiene: navbar scroll effect (agrega clase 'scrolled')
wp_enqueue_script(
'roi-main-js',
get_template_directory_uri() . '/Assets/js/main.js',
array('roi-bootstrap-js'),
'1.0.3', // Cache bust: force remove defer with filter
true // Load in footer
);
// Localize script to pass theme URL to JavaScript
wp_localize_script(
'roi-main-js',
'roiheme',
'1.0.5', // TBT Fase 2.3: eliminado código muerto (~315 → ~25 líneas)
array(
'themeUrl' => get_template_directory_uri(),
'ajaxUrl' => admin_url('admin-ajax.php'),
'in_footer' => true,
'strategy' => 'defer',
)
);
}
add_action('wp_enqueue_scripts', 'roi_enqueue_main_javascript', 11);
/**
* Remove defer from roi-main-js to make wp_localize_script work
* WordPress 6.3+ adds defer automatically to footer scripts with dependencies
* but wp_localize_script requires synchronous execution
*/
function roi_remove_defer_from_main_js($tag, $handle) {
if ('roi-main-js' === $handle) {
// Remove defer and data-wp-strategy attributes
$tag = str_replace(' defer', '', $tag);
$tag = str_replace(' data-wp-strategy="defer"', '', $tag);
}
return $tag;
}
add_filter('script_loader_tag', 'roi_remove_defer_from_main_js', 20, 2);
// ELIMINADO: roi_remove_defer_from_main_js
// Motivo: wp_localize_script ya no se usa, main.js ahora puede usar defer
// Fecha: 2025-11-27 - Optimización TBT Fase 2
/**
* ELIMINADO: roi_enqueue_footer_styles