UNPKG

codewithgarry

Version:

Girish Sharma's NPX business card - DevOps Engineer & Cloud Architect - Connect with me directly via terminal!

320 lines (277 loc) 8.84 kB
/** * Performance Optimization Utilities * Implements lazy loading, caching, and other performance enhancements */ // Lazy loading for images and heavy content class LazyLoader { constructor() { this.observer = null; this.init(); } init() { if ('IntersectionObserver' in window) { this.observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { this.loadElement(entry.target); this.observer.unobserve(entry.target); } }); }, { rootMargin: '50px 0px', threshold: 0.01 }); this.observeElements(); } else { // Fallback for older browsers this.loadAllElements(); } } observeElements() { // Observe images with data-src document.querySelectorAll('img[data-src]').forEach(img => { this.observer.observe(img); }); // Observe lazy-load containers document.querySelectorAll('.lazy-load').forEach(element => { this.observer.observe(element); }); } loadElement(element) { if (element.tagName === 'IMG' && element.dataset.src) { element.src = element.dataset.src; element.classList.add('loaded'); } if (element.classList.contains('lazy-load')) { element.classList.add('loaded'); } } loadAllElements() { document.querySelectorAll('img[data-src]').forEach(img => { this.loadElement(img); }); document.querySelectorAll('.lazy-load').forEach(element => { this.loadElement(element); }); } } // Resource preloader class ResourcePreloader { constructor() { this.cache = new Map(); this.preloadQueue = []; } preloadCSS(href) { if (this.cache.has(href)) return; const link = document.createElement('link'); link.rel = 'preload'; link.as = 'style'; link.href = href; link.onload = () => { link.rel = 'stylesheet'; this.cache.set(href, true); }; document.head.appendChild(link); } preloadJS(src) { if (this.cache.has(src)) return; const link = document.createElement('link'); link.rel = 'preload'; link.as = 'script'; link.href = src; document.head.appendChild(link); this.cache.set(src, true); } preloadImage(src) { if (this.cache.has(src)) return; const img = new Image(); img.onload = () => this.cache.set(src, true); img.src = src; } preloadFont(href) { if (this.cache.has(href)) return; const link = document.createElement('link'); link.rel = 'preload'; link.as = 'font'; link.type = 'font/woff2'; link.crossOrigin = 'anonymous'; link.href = href; document.head.appendChild(link); this.cache.set(href, true); } } // Performance monitor class PerformanceMonitor { constructor() { this.metrics = {}; this.startTime = performance.now(); this.init(); } init() { this.measurePageLoad(); this.measureLCP(); this.measureFID(); this.measureCLS(); } measurePageLoad() { window.addEventListener('load', () => { const loadTime = performance.now() - this.startTime; this.metrics.pageLoadTime = Math.round(loadTime); console.log(`📊 Page loaded in ${this.metrics.pageLoadTime}ms`); }); } measureLCP() { if ('PerformanceObserver' in window) { const observer = new PerformanceObserver((list) => { const entries = list.getEntries(); const lastEntry = entries[entries.length - 1]; this.metrics.lcp = Math.round(lastEntry.startTime); console.log(`📊 LCP: ${this.metrics.lcp}ms`); }); observer.observe({ entryTypes: ['largest-contentful-paint'] }); } } measureFID() { if ('PerformanceObserver' in window) { const observer = new PerformanceObserver((list) => { const firstEntry = list.getEntries()[0]; this.metrics.fid = Math.round(firstEntry.processingStart - firstEntry.startTime); console.log(`📊 FID: ${this.metrics.fid}ms`); }); observer.observe({ entryTypes: ['first-input'] }); } } measureCLS() { if ('PerformanceObserver' in window) { let clsValue = 0; const observer = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { if (!entry.hadRecentInput) { clsValue += entry.value; } } this.metrics.cls = Math.round(clsValue * 1000) / 1000; console.log(`📊 CLS: ${this.metrics.cls}`); }); observer.observe({ entryTypes: ['layout-shift'] }); } } getMetrics() { return this.metrics; } } // Cache management class CacheManager { constructor() { this.storage = window.localStorage; this.prefix = 'cwg_cache_'; this.ttl = 24 * 60 * 60 * 1000; // 24 hours } set(key, value, customTTL = null) { try { const item = { value: value, timestamp: Date.now(), ttl: customTTL || this.ttl }; this.storage.setItem(this.prefix + key, JSON.stringify(item)); } catch (error) { console.warn('Cache set failed:', error); } } get(key) { try { const item = this.storage.getItem(this.prefix + key); if (!item) return null; const parsed = JSON.parse(item); if (Date.now() - parsed.timestamp > parsed.ttl) { this.delete(key); return null; } return parsed.value; } catch (error) { console.warn('Cache get failed:', error); return null; } } delete(key) { try { this.storage.removeItem(this.prefix + key); } catch (error) { console.warn('Cache delete failed:', error); } } clear() { try { Object.keys(this.storage).forEach(key => { if (key.startsWith(this.prefix)) { this.storage.removeItem(key); } }); } catch (error) { console.warn('Cache clear failed:', error); } } } // Initialize performance optimizations function initPerformanceOptimizations() { // Initialize lazy loading const lazyLoader = new LazyLoader(); // Initialize resource preloader const preloader = new ResourcePreloader(); // Preload critical resources preloader.preloadFont('https://fonts.gstatic.com/s/firacode/v21/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJVD7MOzlojwUKaJO.woff2'); preloader.preloadCSS('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css'); // Initialize performance monitoring const monitor = new PerformanceMonitor(); // Initialize cache const cache = new CacheManager(); // Add to global scope for access window.performance_utils = { lazyLoader, preloader, monitor, cache }; console.log('🚀 Performance optimizations initialized'); } // Debounce utility for performance function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } // Throttle utility for performance function throttle(func, limit) { let inThrottle; return function(...args) { if (!inThrottle) { func.apply(this, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initPerformanceOptimizations); } else { initPerformanceOptimizations(); } // Export for Node.js environment if (typeof module !== 'undefined' && module.exports) { module.exports = { LazyLoader, ResourcePreloader, PerformanceMonitor, CacheManager, debounce, throttle }; }