perf(me.html): 优化DOM访问以提升页面性能
- 引入DOM_CACHE对象缓存频繁访问的DOM元素 - 修改safeUpdateText和safeClass函数以接受DOM元素而非ID - 替换所有document.getElementById调用为DOM_CACHE中的缓存引用 - 减少重复DOM查询,提高渲染和交互性能
This commit is contained in:
92
me.html
92
me.html
@@ -406,15 +406,39 @@
|
|||||||
|
|
||||||
APP_STATE.namasteStableFrames = 0;
|
APP_STATE.namasteStableFrames = 0;
|
||||||
|
|
||||||
|
// 缓存频繁访问的DOM元素以提高性能
|
||||||
|
const DOM_CACHE = {
|
||||||
|
// 加载屏幕相关元素
|
||||||
|
startScreen: document.getElementById('start-screen'),
|
||||||
|
loaderMsg: document.getElementById('loader-msg'),
|
||||||
|
permHint: document.getElementById('perm-guide'),
|
||||||
|
|
||||||
|
// 叙事层相关元素
|
||||||
|
narrativeLayer: document.getElementById('narrative-layer'),
|
||||||
|
nTitle: document.getElementById('n-title'),
|
||||||
|
nSub: document.getElementById('n-sub'),
|
||||||
|
|
||||||
|
// UI层相关元素
|
||||||
|
uiLayer: document.getElementById('ui-layer'),
|
||||||
|
sysStatus: document.getElementById('sys-status'),
|
||||||
|
themeDisplay: document.getElementById('theme-display'),
|
||||||
|
langDisplay: document.getElementById('lang-display'),
|
||||||
|
mainHint: document.getElementById('main-hint'),
|
||||||
|
subHint: document.getElementById('sub-hint'),
|
||||||
|
exitBtn: document.getElementById('exit-btn'),
|
||||||
|
|
||||||
|
// 其他元素
|
||||||
|
canvasContainer: document.getElementById('canvas-container'),
|
||||||
|
inputVideo: document.getElementById('input-video')
|
||||||
|
};
|
||||||
|
|
||||||
// 安全DOM操作,防止报错
|
// 安全DOM操作,防止报错
|
||||||
function safeUpdateText(id, text) {
|
function safeUpdateText(element, text) {
|
||||||
const el = document.getElementById(id);
|
if (element) element.innerText = text;
|
||||||
if (el) el.innerText = text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function safeClass(id, method, className) {
|
function safeClass(element, method, className) {
|
||||||
const el = document.getElementById(id);
|
if (element) element.classList[method](className);
|
||||||
if (el) el.classList[method](className);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -451,8 +475,8 @@
|
|||||||
|
|
||||||
// 应用主题
|
// 应用主题
|
||||||
document.documentElement.setAttribute('data-theme', ENV.theme);
|
document.documentElement.setAttribute('data-theme', ENV.theme);
|
||||||
safeUpdateText('theme-display', `THEME: ${ENV.lang.toUpperCase() === 'en' ? ENV.theme.toUpperCase() : ENV.theme === 'day' ? '白天' : '黑夜'}`);
|
safeUpdateText(DOM_CACHE.themeDisplay, `THEME: ${ENV.lang.toUpperCase() === 'en' ? ENV.theme.toUpperCase() : ENV.theme === 'day' ? '白天' : '黑夜'}`);
|
||||||
safeUpdateText('lang-display', ENV.lang.toUpperCase() === 'CN' ? '中文' : 'English');
|
safeUpdateText(DOM_CACHE.langDisplay, ENV.lang.toUpperCase() === 'CN' ? '中文' : 'English');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ============================================================================
|
* ============================================================================
|
||||||
@@ -508,17 +532,17 @@
|
|||||||
clearInterval(loadTimer);
|
clearInterval(loadTimer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
safeUpdateText('loader-msg', CONTENT.load[loadIdx > maxIdx ? maxIdx : loadIdx]);
|
safeUpdateText(DOM_CACHE.loaderMsg, CONTENT.load[loadIdx > maxIdx ? maxIdx : loadIdx]);
|
||||||
loadIdx++;
|
loadIdx++;
|
||||||
}, 600);
|
}, 600);
|
||||||
|
|
||||||
// 权限超时提示
|
// 权限超时提示
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!APP_STATE.isLoaded) safeClass('perm-hint', 'add', 'show');
|
if (!APP_STATE.isLoaded) safeClass(DOM_CACHE.permHint, 'add', 'show');
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
safeUpdateText('main-hint', CONTENT.hints.main);
|
safeUpdateText(DOM_CACHE.mainHint, CONTENT.hints.main);
|
||||||
safeUpdateText('sub-hint', CONTENT.hints.sub);
|
safeUpdateText(DOM_CACHE.subHint, CONTENT.hints.sub);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ============================================================================
|
* ============================================================================
|
||||||
@@ -548,7 +572,7 @@
|
|||||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||||
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
||||||
renderer.setClearColor(0x000000, 0);
|
renderer.setClearColor(0x000000, 0);
|
||||||
document.getElementById('canvas-container').appendChild(renderer.domElement);
|
DOM_CACHE.canvasContainer.appendChild(renderer.domElement);
|
||||||
|
|
||||||
const composer = new THREE.EffectComposer(renderer);
|
const composer = new THREE.EffectComposer(renderer);
|
||||||
composer.addPass(new THREE.RenderPass(scene, camera));
|
composer.addPass(new THREE.RenderPass(scene, camera));
|
||||||
@@ -789,10 +813,10 @@
|
|||||||
APP_STATE.mode = 'UNLOCKED';
|
APP_STATE.mode = 'UNLOCKED';
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
safeClass('main-hint', 'add', 'hidden'); // 隐藏主提示 (CSS需支持或直接display)
|
safeClass(DOM_CACHE.mainHint, 'add', 'hidden'); // 隐藏主提示 (CSS需支持或直接display)
|
||||||
document.getElementById('main-hint').style.display = 'none';
|
DOM_CACHE.mainHint.style.display = 'none';
|
||||||
document.getElementById('sub-hint').style.display = 'none';
|
DOM_CACHE.subHint.style.display = 'none';
|
||||||
safeClass('exit-btn', 'add', 'visible');
|
safeClass(DOM_CACHE.exitBtn, 'add', 'visible');
|
||||||
|
|
||||||
// 粒子爆炸效果
|
// 粒子爆炸效果
|
||||||
explode(100);
|
explode(100);
|
||||||
@@ -804,13 +828,13 @@
|
|||||||
APP_STATE.mode = 'LOCKED';
|
APP_STATE.mode = 'LOCKED';
|
||||||
APP_STATE.exitCooldownUntil = Date.now() + 2000;
|
APP_STATE.exitCooldownUntil = Date.now() + 2000;
|
||||||
|
|
||||||
document.getElementById('main-hint').style.display = 'block';
|
DOM_CACHE.mainHint.style.display = 'block';
|
||||||
document.getElementById('sub-hint').style.display = 'block';
|
DOM_CACHE.subHint.style.display = 'block';
|
||||||
safeClass('exit-btn', 'remove', 'visible');
|
safeClass(DOM_CACHE.exitBtn, 'remove', 'visible');
|
||||||
safeClass('narrative-layer', 'remove', 'show-text');
|
safeClass(DOM_CACHE.narrativeLayer, 'remove', 'show-text');
|
||||||
|
|
||||||
APP_STATE.unlockProgress = 0;
|
APP_STATE.unlockProgress = 0;
|
||||||
safeUpdateText('main-hint', CONTENT.hints.main);
|
safeUpdateText(DOM_CACHE.mainHint, CONTENT.hints.main);
|
||||||
clearTimeout(narrativeTimer);
|
clearTimeout(narrativeTimer);
|
||||||
explode(50);
|
explode(50);
|
||||||
}
|
}
|
||||||
@@ -825,9 +849,9 @@
|
|||||||
|
|
||||||
function startNarrative() {
|
function startNarrative() {
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
const nTitle = document.getElementById('n-title');
|
const nTitle = DOM_CACHE.nTitle;
|
||||||
const nSub = document.getElementById('n-sub');
|
const nSub = DOM_CACHE.nSub;
|
||||||
const layer = document.getElementById('narrative-layer');
|
const layer = DOM_CACHE.narrativeLayer;
|
||||||
|
|
||||||
// 必须检查元素是否存在
|
// 必须检查元素是否存在
|
||||||
if (!nTitle || !nSub || !layer) return;
|
if (!nTitle || !nSub || !layer) return;
|
||||||
@@ -873,18 +897,18 @@
|
|||||||
// Loader logic
|
// Loader logic
|
||||||
if (!APP_STATE.isLoaded) {
|
if (!APP_STATE.isLoaded) {
|
||||||
APP_STATE.isLoaded = true;
|
APP_STATE.isLoaded = true;
|
||||||
const loader = document.getElementById('start-screen');
|
const loader = DOM_CACHE.startScreen;
|
||||||
loader.style.opacity = 0;
|
loader.style.opacity = 0;
|
||||||
document.getElementById('ui-layer').style.opacity = 1;
|
DOM_CACHE.uiLayer.style.opacity = 1;
|
||||||
setTimeout(() => loader.style.display = 'none', 1000);
|
setTimeout(() => loader.style.display = 'none', 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
const landmarks = results.multiHandLandmarks;
|
const landmarks = results.multiHandLandmarks;
|
||||||
const sysStatus = document.getElementById('sys-status');
|
const sysStatus = DOM_CACHE.sysStatus;
|
||||||
|
|
||||||
if (landmarks && landmarks.length > 0) {
|
if (landmarks && landmarks.length > 0) {
|
||||||
APP_STATE.handCount = landmarks.length;
|
APP_STATE.handCount = landmarks.length;
|
||||||
safeUpdateText('sys-status', `LINKED (${APP_STATE.handCount})`);
|
safeUpdateText(sysStatus, `LINKED (${APP_STATE.handCount})`);
|
||||||
if (sysStatus) sysStatus.style.color = ENV.theme === 'day' ? '#0044cc' : '#00ff00';
|
if (sysStatus) sysStatus.style.color = ENV.theme === 'day' ? '#0044cc' : '#00ff00';
|
||||||
|
|
||||||
// 坐标处理 (镜像)
|
// 坐标处理 (镜像)
|
||||||
@@ -922,20 +946,20 @@
|
|||||||
}
|
}
|
||||||
const targetFrames = 20;
|
const targetFrames = 20;
|
||||||
const pct = Math.min(100, Math.round(APP_STATE.namasteStableFrames / targetFrames * 100));
|
const pct = Math.min(100, Math.round(APP_STATE.namasteStableFrames / targetFrames * 100));
|
||||||
if (pct > 0) safeUpdateText('main-hint', `${CONTENT.hints.unlocking} ${pct}%`);
|
if (pct > 0) safeUpdateText(DOM_CACHE.mainHint, `${CONTENT.hints.unlocking} ${pct}%`);
|
||||||
if (APP_STATE.namasteStableFrames >= targetFrames) enterArchive();
|
if (APP_STATE.namasteStableFrames >= targetFrames) enterArchive();
|
||||||
if (!ok && APP_STATE.namasteStableFrames === 0) safeUpdateText('main-hint', CONTENT.hints.main);
|
if (!ok && APP_STATE.namasteStableFrames === 0) safeUpdateText(DOM_CACHE.mainHint, CONTENT.hints.main);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
APP_STATE.handCount = 0;
|
APP_STATE.handCount = 0;
|
||||||
safeUpdateText('sys-status', 'SEARCHING...');
|
safeUpdateText(sysStatus, 'SEARCHING...');
|
||||||
if (sysStatus) sysStatus.style.color = 'inherit';
|
if (sysStatus) sysStatus.style.color = 'inherit';
|
||||||
APP_STATE.unlockProgress = 0;
|
APP_STATE.unlockProgress = 0;
|
||||||
safeUpdateText('main-hint', CONTENT.hints.main);
|
safeUpdateText(DOM_CACHE.mainHint, CONTENT.hints.main);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const videoElement = document.getElementById('input-video');
|
const videoElement = DOM_CACHE.inputVideo;
|
||||||
const cameraUtils = new Camera(videoElement, {
|
const cameraUtils = new Camera(videoElement, {
|
||||||
onFrame: async () => {
|
onFrame: async () => {
|
||||||
await hands.send({image: videoElement});
|
await hands.send({image: videoElement});
|
||||||
|
|||||||
Reference in New Issue
Block a user