From 446ae5c5a703c9406fd584b676a1cf9f5a12c8be Mon Sep 17 00:00:00 2001 From: oiupoyt Date: Sat, 12 Sep 2026 16:54:20 +0530 Subject: [PATCH] perf: comprehensive runtime optimizations (zero GC churn, RAF decoupling, layout containment) --- index.html | 149 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 53 deletions(-) diff --git a/index.html b/index.html index 9b4a76c..73ff5ea 100644 --- a/index.html +++ b/index.html @@ -147,6 +147,9 @@ z-index: 10; display: flex; flex-direction: column; + transform: translateZ(0); + backface-visibility: hidden; + contain: layout style; transition: border-color 0.18s ease, box-shadow 0.18s ease, background 0.18s ease; } @@ -1090,27 +1093,34 @@ const shiftX = e.clientX - rect.left; const shiftY = e.clientY - rect.top; + win.style.willChange = 'left, top'; + let dragRaf = null; + function onMouseMove(moveEvent) { - let newX = moveEvent.clientX - shiftX; - let newY = moveEvent.clientY - shiftY; + const newX = Math.max(0, Math.min(window.innerWidth - 60, moveEvent.clientX - shiftX)); + const newY = Math.max(0, Math.min(window.innerHeight - 70, moveEvent.clientY - shiftY)); - const maxX = window.innerWidth - 60; - const maxY = window.innerHeight - 70; - if (newX < 0) newX = 0; - if (newX > maxX) newX = maxX; - if (newY < 0) newY = 0; - if (newY > maxY) newY = maxY; - - win.style.left = newX + 'px'; - win.style.top = newY + 'px'; + if (!dragRaf) { + dragRaf = requestAnimationFrame(() => { + win.style.left = newX + 'px'; + win.style.top = newY + 'px'; + dragRaf = null; + }); + } } function onMouseUp() { + if (dragRaf) { + cancelAnimationFrame(dragRaf); + dragRaf = null; + } + win.style.willChange = 'auto'; document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); + if (win.id === 'win-viz' && typeof resizeVizCanvas === 'function') resizeVizCanvas(); } - document.addEventListener('mousemove', onMouseMove); + document.addEventListener('mousemove', onMouseMove, { passive: true }); document.addEventListener('mouseup', onMouseUp); }); }); @@ -1214,6 +1224,7 @@ if (e.key === 'Enter') { const cmd = termInput.value.trim(); if (cmd) { + if (cmdHistory.length > 60) cmdHistory.shift(); cmdHistory.push(cmd); historyIdx = cmdHistory.length; execCommand(cmd); @@ -1247,6 +1258,11 @@ const cmd = parts[0].toLowerCase(); const arg = parts.slice(1).join(' '); + // Prune old terminal nodes to keep DOM lightweight + while (termHistory.children.length > 60) { + termHistory.removeChild(termHistory.firstChild); + } + const row = document.createElement('div'); row.innerHTML = `oiupoyt@archlinux:~$ ${escapeHtml(cmdLine)}`; termHistory.appendChild(row); @@ -1498,16 +1514,19 @@ vizCanvas.addEventListener('click', cycleVizMode); + const sharedFreqData = new Uint8Array(128); + function resizeVizCanvas() { const rect = vizCanvas.getBoundingClientRect(); - const dpr = window.devicePixelRatio || 1; - vizCanvas.width = rect.width * dpr; - vizCanvas.height = rect.height * dpr; + const dpr = Math.min(window.devicePixelRatio || 1, 2); + vizCanvas.width = (rect.width || 500) * dpr; + vizCanvas.height = (rect.height || 240) * dpr; } function startVisualizer() { if (!analyser) return; vizIdleMsg.style.opacity = '0'; + resizeVizCanvas(); cancelAnimationFrame(vizAnimId); drawVisualizerFrame(); } @@ -1532,7 +1551,7 @@ function drawVisualizerFrame() { vizAnimId = requestAnimationFrame(drawVisualizerFrame); - resizeVizCanvas(); + if (document.hidden) return; // Pause rendering on inactive tab const W = vizCanvas.width; const H = vizCanvas.height; @@ -1540,9 +1559,9 @@ vizCtx.clearRect(0, 0, W, H); - const bufLen = analyser.frequencyBinCount; - const freqData = new Uint8Array(bufLen); - analyser.getByteFrequencyData(freqData); + analyser.getByteFrequencyData(sharedFreqData); + const freqData = sharedFreqData; + const bufLen = sharedFreqData.length; const mode = vizModes[currentVizModeIdx]; @@ -1634,6 +1653,13 @@ }, 1900); } + function safeStorageGet(key, def = null) { + try { return localStorage.getItem(key) || def; } catch(e) { return def; } + } + function safeStorageSet(key, val) { + try { localStorage.setItem(key, val); } catch(e) {} + } + const bgModes = [ { id: 'liquid-void', name: 'Liquid Void Fluid' }, { id: 'cyber-horizon', name: 'Cyber 3D Horizon' }, @@ -1641,13 +1667,13 @@ { id: 'video-ambient', name: 'Ambient Video' } ]; let currentBgModeIdx = 0; // Default: 'liquid-void' - const savedBg = localStorage.getItem('katos_bg_mode'); + const savedBg = safeStorageGet('katos_bg_mode'); if (savedBg && savedBg !== 'video-ambient') { const idx = bgModes.findIndex(m => m.id === savedBg); if (idx !== -1) currentBgModeIdx = idx; } else { currentBgModeIdx = 0; - localStorage.setItem('katos_bg_mode', 'liquid-void'); + safeStorageSet('katos_bg_mode', 'liquid-void'); } function setBgMode(modeId, silent = false) { @@ -1665,7 +1691,7 @@ function applyBgMode(silent = false) { const mode = bgModes[currentBgModeIdx]; - localStorage.setItem('katos_bg_mode', mode.id); + safeStorageSet('katos_bg_mode', mode.id); if (mode.id === 'video-ambient') { bgVideo.style.display = 'block'; tryLoadBgVideo(); @@ -1695,16 +1721,17 @@ bgMouse.targetX = e.clientX; bgMouse.targetY = e.clientY; bgMouse.active = true; - }); + }, { passive: true }); window.addEventListener('mouseleave', () => { bgMouse.active = false; - }); + }, { passive: true }); // Gravitational Shockwaves on Click const shockwaves = []; window.addEventListener('mousedown', e => { if (e.target.closest('.window-body') || e.target.closest('input') || e.target.closest('.player-btn')) return; + if (shockwaves.length > 5) shockwaves.shift(); shockwaves.push({ x: e.clientX, y: e.clientY, @@ -1715,6 +1742,13 @@ }); }); + // Pause CPU/GPU canvas rendering when user switches tabs or minimizes window + document.addEventListener('visibilitychange', () => { + if (!document.hidden && isPlaying) { + startVisualizer(); + } + }); + // ── Liquid Void Kinetic Particle Fluid ────────────────────────────────── const FLUID_PARTICLE_COUNT = 380; const fluidParticles = []; @@ -1742,14 +1776,19 @@ } } - // Incompressible Curl-Noise Flow Field Generator (Zero Divergence) - function getCurlVector(x, y, t) { + // Incompressible Curl-Noise Flow Field Generator (Zero Allocation & Fast Math) + let curlVx = 0, curlVy = 0; + function computeCurl(x, y, t) { const s1 = 0.0016; const s2 = 0.0034; - const vx = -s1 * Math.sin(x * s1 + t * 0.00035) * Math.sin(y * s1 + t * 0.0003) + 0.45 * s2 * Math.cos((x + y) * s2 - t * 0.00045); - const vy = -(s1 * Math.cos(x * s1 + t * 0.00035) * Math.cos(y * s1 + t * 0.0003) + 0.45 * s2 * Math.cos((x + y) * s2 - t * 0.00045)); - const len = Math.hypot(vx, vy) || 1; - return { vx: vx / len, vy: vy / len }; + const t1 = t * 0.00035; + const t2 = t * 0.0003; + const t3 = t * 0.00045; + const vx = -s1 * Math.sin(x * s1 + t1) * Math.sin(y * s1 + t2) + 0.45 * s2 * Math.cos((x + y) * s2 - t3); + const vy = -(s1 * Math.cos(x * s1 + t1) * Math.sin(y * s1 + t2) + 0.45 * s2 * Math.cos((x + y) * s2 - t3)); + const invLen = 1 / (Math.sqrt(vx * vx + vy * vy) || 1); + curlVx = vx * invLen; + curlVy = vy * invLen; } // Matrix Rain Setup @@ -1766,19 +1805,19 @@ bgCanvas.height = window.innerHeight; initFluidParticles(); initMatrixDrops(); + if (typeof resizeVizCanvas === 'function') resizeVizCanvas(); } window.addEventListener('resize', resizeBgCanvas); resizeBgCanvas(); - // Audio frequency extractor + // Audio frequency extractor (zero garbage collection overhead) function getAudioBeat() { if (!isPlaying || !analyser) return { bass: 0, mid: 0, energy: 0 }; - const freqData = new Uint8Array(analyser.frequencyBinCount); - analyser.getByteFrequencyData(freqData); - let bSum = 0; for (let i = 0; i < 5; i++) bSum += freqData[i]; - let mSum = 0; for (let i = 5; i < 20; i++) mSum += freqData[i]; - const bass = (bSum / 5) / 255; - const mid = (mSum / 15) / 255; + analyser.getByteFrequencyData(sharedFreqData); + let bSum = 0; for (let i = 0; i < 5; i++) bSum += sharedFreqData[i]; + let mSum = 0; for (let i = 5; i < 20; i++) mSum += sharedFreqData[i]; + const bass = (bSum * 0.2) * 0.00392156862745098; + const mid = (mSum * 0.06666666666666667) * 0.00392156862745098; return { bass, mid, energy: (bass * 0.65 + mid * 0.35) }; } @@ -1787,6 +1826,7 @@ function renderBgFrame(timestamp) { requestAnimationFrame(renderBgFrame); + if (document.hidden) return; // Full GPU/CPU pause on inactive tab const W = bgCanvas.width; const H = bgCanvas.height; if (W === 0 || H === 0) return; @@ -1876,28 +1916,30 @@ p.oldX = p.x; p.oldY = p.y; - // 1. Natural Incompressible Curl Flow Field - const curl = getCurlVector(p.x, p.y, timestamp); - p.vx += curl.vx * 0.22 * p.speed; - p.vy += curl.vy * 0.22 * p.speed; + // 1. Natural Incompressible Curl Flow Field (Zero Allocation) + computeCurl(p.x, p.y, timestamp); + p.vx += curlVx * 0.22 * p.speed; + p.vy += curlVy * 0.22 * p.speed; // 2. Interactive Mouse Vortex & Kinetic Attraction if (bgMouse.active) { const mdx = bgMouse.x - p.x; const mdy = bgMouse.y - p.y; - const mDist = Math.hypot(mdx, mdy); - if (mDist < 220 && mDist > 0.001) { - const factor = (1 - mDist / 220); + const mDistSq = mdx * mdx + mdy * mdy; + if (mDistSq < 48400 && mDistSq > 0.0001) { + const mDist = Math.sqrt(mDistSq); + const factor = (1 - mDist * 0.00454545); + const invMDist = 1 / mDist; // Tangential vortex whirlpool force - const swirlX = -mdy / mDist; - const swirlY = mdx / mDist; + const swirlX = -mdy * invMDist; + const swirlY = mdx * invMDist; p.vx += swirlX * factor * 2.8; p.vy += swirlY * factor * 2.8; // Gentle radial pull into the vortex center - p.vx += (mdx / mDist) * factor * 1.1; - p.vy += (mdy / mDist) * factor * 1.1; + p.vx += (mdx * invMDist) * factor * 1.1; + p.vy += (mdy * invMDist) * factor * 1.1; // Kinetic velocity transfer from rapid cursor movement p.vx += bgMouse.vx * factor * 0.18; @@ -1910,12 +1952,13 @@ const sw = shockwaves[k]; const sdx = p.x - sw.x; const sdy = p.y - sw.y; - const sDist = Math.hypot(sdx, sdy); + const sDist = Math.sqrt(sdx * sdx + sdy * sdy); const ringDist = Math.abs(sDist - sw.radius); if (ringDist < 45 && sDist > 0.001) { - const push = (1 - ringDist / 45) * 3.5 * sw.alpha * sw.power; - p.vx += (sdx / sDist) * push; - p.vy += (sdy / sDist) * push; + const push = (1 - ringDist * 0.02222) * 3.5 * sw.alpha * sw.power; + const invSDist = 1 / sDist; + p.vx += (sdx * invSDist) * push; + p.vy += (sdy * invSDist) * push; } } @@ -1939,7 +1982,7 @@ } // 4. Render Silky Luminous Trail - const vMag = Math.hypot(p.vx, p.vy); + const vMag = Math.sqrt(p.vx * p.vx + p.vy * p.vy); const glowAlpha = Math.min(1, p.alpha * (0.8 + audio.bass * 0.9) + vMag * 0.08); bgCtx.strokeStyle = `rgba(255, 255, 255, ${glowAlpha})`;