1/** 2 * performance.js â Mobile Performance Optimizations 3 * âââââââââââââââââââââââââââââââââââââââââââââââââ 4 * Reduces animations and effects on mobile devices 5 * to improve loading and runtime performance. 6 */ 7 8(function() { 9 'use strict'; 10 11 // Detect mobile devices 12 const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); 13 const isLowEndDevice = navigator.hardwareConcurrency && navigator.hardwareConcurrency <= 4; 14 15 if (isMobile || isLowEndDevice) { 16 // Add class to body for mobile-specific optimizations 17 document.documentElement.classList.add('mobile-optimized'); 18 19 // Disable smooth scroll on low-end devices 20 if (isLowEndDevice && window.lenis) { 21 window.lenis.destroy(); 22 document.documentElement.style.scrollBehavior = 'auto'; 23 } 24 25 // Reduce animation complexity 26 const style = document.createElement('style'); 27 style.textContent = ` 28 /* Disable heavy animations on mobile */ 29 .mobile-optimized .visualizer, 30 .mobile-optimized body::after { 31 display: none !important; 32 } 33 34 /* Simplify transitions */ 35 .mobile-optimized * { 36 animation-duration: 0.2s !important; 37 transition-duration: 0.2s !important; 38 } 39 40 /* Disable backdrop filters on low-end devices */ 41 ${isLowEndDevice ? ` 42 .mobile-optimized .media-card, 43 .mobile-optimized .utility-card, 44 .mobile-optimized .command-card, 45 .mobile-optimized .cta-card { 46 backdrop-filter: none !important; 47 -webkit-backdrop-filter: none !important; 48 } 49 ` : ''} 50 `; 51 document.head.appendChild(style); 52 } 53 54 // Lazy load images 55 if ('loading' in HTMLImageElement.prototype) { 56 const images = document.querySelectorAll('img[data-src]'); 57 images.forEach(img => { 58 img.src = img.dataset.src; 59 }); 60 } else { 61 // Fallback for browsers that don't support lazy loading 62 const script = document.createElement('script'); 63 script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/lazysizes.min.js'; 64 document.body.appendChild(script); 65 } 66 67 // Preload critical resources only 68 const preloadCritical = () => { 69 // Preload hero image 70 const link = document.createElement('link'); 71 link.rel = 'preload'; 72 link.as = 'image'; 73 link.href = 'assets/images/background.webp'; 74 document.head.appendChild(link); 75 }; 76 77 // Run on DOM ready 78 if (document.readyState === 'loading') { 79 document.addEventListener('DOMContentLoaded', preloadCritical); 80 } else { 81 preloadCritical(); 82 } 83 84 // Hide WidgetBot on mobile to avoid overlap with Add to Discord button 85 if (isMobile) { 86 const hideWidgetBot = () => { 87 const crate = document.querySelector('.crate') || 88 document.querySelector('[class*="crate"]') || 89 document.querySelector('body > div[style*="position: fixed"][style*="bottom"]'); 90 91 if (crate) { 92 crate.style.display = 'none'; 93 } 94 }; 95 96 // Try multiple times as WidgetBot loads asynchronously 97 setTimeout(hideWidgetBot, 500); 98 setTimeout(hideWidgetBot, 1500); 99 setTimeout(hideWidgetBot, 3000); 100 101 // Also observe for when the element appears 102 const observer = new MutationObserver(hideWidgetBot); 103 observer.observe(document.body, { childList: true, subtree: true }); 104 105 // Stop observing after 5 seconds 106 setTimeout(() => observer.disconnect(), 5000); 107 } 108 109})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.