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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user