File: /mnt/data/doccure-io/wp-content/plugins/wp-performance-optimizer/js/frontend.js
/**
* WP Performance Optimizer - Frontend JavaScript
* Version: 2.1.4
* Author: Performance Solutions Inc.
*/
(function() {
'use strict';
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', WPPOFrontend.init);
} else {
WPPOFrontend.init();
}
// Main frontend object
window.WPPOFrontend = {
// Configuration
config: {
debugMode: false,
showPerformanceIndicator: false,
cacheWarmingEnabled: true,
lazyLoadingEnabled: true
},
// Initialize frontend functionality
init: function() {
this.loadConfig();
this.setupPerformanceMonitoring();
this.setupLazyLoading();
this.setupCacheWarming();
this.setupPerformanceIndicator();
},
// Load configuration from WordPress
loadConfig: function() {
// Check for debug mode
if (window.location.search.indexOf('wppo_debug=1') !== -1) {
this.config.debugMode = true;
}
},
// Setup performance monitoring
setupPerformanceMonitoring: function() {
var self = this;
// Monitor page load performance
window.addEventListener('load', function() {
self.measurePagePerformance();
});
// Monitor user interactions
this.monitorUserInteractions();
},
// Measure page performance
measurePagePerformance: function() {
if (!window.performance || !window.performance.timing) {
return;
}
var timing = window.performance.timing;
var performance = {
domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart,
loadComplete: timing.loadEventEnd - timing.navigationStart,
firstPaint: this.getFirstPaint(),
resourceCount: this.getResourceCount()
};
// Store performance data
this.storePerformanceData(performance);
// Show debug info if enabled
if (this.config.debugMode) {
this.showDebugInfo(performance);
}
},
// Get first paint time
getFirstPaint: function() {
if (window.performance && window.performance.getEntriesByType) {
var paintEntries = window.performance.getEntriesByType('paint');
var firstPaint = paintEntries.find(function(entry) {
return entry.name === 'first-paint';
});
return firstPaint ? firstPaint.startTime : 0;
}
return 0;
},
// Get resource count
getResourceCount: function() {
if (window.performance && window.performance.getEntriesByType) {
return window.performance.getEntriesByType('resource').length;
}
return 0;
},
// Store performance data
storePerformanceData: function(data) {
// Store in localStorage for caching
try {
localStorage.setItem('wppo_performance_data', JSON.stringify({
timestamp: Date.now(),
data: data
}));
} catch (e) {
// Ignore localStorage errors
}
},
// Monitor user interactions
monitorUserInteractions: function() {
var self = this;
var interactionCount = 0;
// Track clicks
document.addEventListener('click', function(e) {
interactionCount++;
self.trackInteraction('click', e.target);
});
// Track scrolls
var scrollTimeout;
window.addEventListener('scroll', function() {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(function() {
self.trackInteraction('scroll', null);
}, 100);
});
// Track form submissions
document.addEventListener('submit', function(e) {
self.trackInteraction('form_submit', e.target);
});
},
// Track user interaction
trackInteraction: function(type, element) {
var data = {
type: type,
timestamp: Date.now(),
url: window.location.href,
element: element ? element.tagName : null
};
// Store interaction data
this.storeInteractionData(data);
},
// Store interaction data
storeInteractionData: function(data) {
try {
var interactions = JSON.parse(localStorage.getItem('wppo_interactions') || '[]');
interactions.push(data);
// Keep only last 50 interactions
if (interactions.length > 50) {
interactions = interactions.slice(-50);
}
localStorage.setItem('wppo_interactions', JSON.stringify(interactions));
} catch (e) {
// Ignore localStorage errors
}
},
// Setup lazy loading
setupLazyLoading: function() {
if (!this.config.lazyLoadingEnabled) {
return;
}
var self = this;
var lazyImages = document.querySelectorAll('img[data-src]');
if ('IntersectionObserver' in window) {
var imageObserver = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var img = entry.target;
img.src = img.dataset.src;
img.classList.remove('wppo-lazy-placeholder');
imageObserver.unobserve(img);
}
});
});
lazyImages.forEach(function(img) {
imageObserver.observe(img);
});
} else {
// Fallback for older browsers
lazyImages.forEach(function(img) {
img.src = img.dataset.src;
img.classList.remove('wppo-lazy-placeholder');
});
}
},
// Setup cache warming
setupCacheWarming: function() {
if (!this.config.cacheWarmingEnabled) {
return;
}
var self = this;
// Show cache warming indicator
setTimeout(function() {
self.showCacheWarmingIndicator();
}, 1000);
// Preload critical resources
this.preloadCriticalResources();
},
// Show cache warming indicator
showCacheWarmingIndicator: function() {
var indicator = document.createElement('div');
indicator.className = 'wppo-cache-warming';
indicator.innerHTML = '🔥 Warming cache for better performance...';
document.body.appendChild(indicator);
// Show indicator
setTimeout(function() {
indicator.classList.add('show');
}, 100);
// Hide after 3 seconds
setTimeout(function() {
indicator.classList.remove('show');
setTimeout(function() {
document.body.removeChild(indicator);
}, 300);
}, 3000);
},
// Preload critical resources
preloadCriticalResources: function() {
var criticalLinks = document.querySelectorAll('a[href]');
var preloadedUrls = new Set();
criticalLinks.forEach(function(link) {
var href = link.href;
if (href && !preloadedUrls.has(href) && preloadedUrls.size < 5) {
preloadedUrls.add(href);
// Create preload link
var preloadLink = document.createElement('link');
preloadLink.rel = 'prefetch';
preloadLink.href = href;
document.head.appendChild(preloadLink);
}
});
},
// Setup performance indicator
setupPerformanceIndicator: function() {
if (!this.config.showPerformanceIndicator) {
return;
}
var self = this;
// Create performance indicator
var indicator = document.createElement('div');
indicator.className = 'wppo-perf-indicator';
indicator.innerHTML = 'âš¡ Performance: <span id="wppo-perf-value">Loading...</span>';
document.body.appendChild(indicator);
// Update performance value
window.addEventListener('load', function() {
var loadTime = self.measurePagePerformance();
var perfValue = document.getElementById('wppo-perf-value');
if (perfValue) {
perfValue.textContent = loadTime + 'ms';
indicator.classList.add('show');
}
});
},
// Show debug information
showDebugInfo: function(performance) {
var debugOverlay = document.createElement('div');
debugOverlay.className = 'wppo-debug-overlay';
debugOverlay.innerHTML = this.generateDebugHTML(performance);
document.body.appendChild(debugOverlay);
// Show overlay
setTimeout(function() {
debugOverlay.classList.add('show');
}, 100);
// Hide on escape key
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
debugOverlay.classList.remove('show');
setTimeout(function() {
document.body.removeChild(debugOverlay);
}, 300);
}
});
},
// Generate debug HTML
generateDebugHTML: function(performance) {
return '<div class="wppo-debug-content">' +
'<h3 class="wppo-debug-title">WP Performance Optimizer - Debug Info</h3>' +
'<div class="wppo-debug-metric">' +
'<span class="wppo-debug-label">DOM Content Loaded:</span>' +
'<span class="wppo-debug-value">' + performance.domContentLoaded + 'ms</span>' +
'</div>' +
'<div class="wppo-debug-metric">' +
'<span class="wppo-debug-label">Load Complete:</span>' +
'<span class="wppo-debug-value">' + performance.loadComplete + 'ms</span>' +
'</div>' +
'<div class="wppo-debug-metric">' +
'<span class="wppo-debug-label">First Paint:</span>' +
'<span class="wppo-debug-value">' + performance.firstPaint + 'ms</span>' +
'</div>' +
'<div class="wppo-debug-metric">' +
'<span class="wppo-debug-label">Resource Count:</span>' +
'<span class="wppo-debug-value">' + performance.resourceCount + '</span>' +
'</div>' +
'<p style="margin-top: 20px; color: #999; font-size: 12px;">Press ESC to close</p>' +
'</div>';
}
};
})();