Reduce performance lost on large screens
Some checks failed
Deploy with Docker Compose / deploy (push) Has been cancelled

This commit is contained in:
2026-03-09 16:41:55 +00:00
parent d03f9668ad
commit 141ceab7e6
3 changed files with 93 additions and 28 deletions

View File

@@ -23,49 +23,83 @@ const phrases = [
"I like anime, all kinds of music and sci fic",
];
// Non-reactive animation state to avoid triggering Vue re-renders every frame
const animState = phrases.map((text, i) => ({
x: i * 20,
y: i * 20,
dx: rand(0, 30) / 100,
dy: 0.5,
content: text,
cachedW: 0,
cachedH: 0,
}));
// Reactive items only for initial render
const items = ref<Item[]>(
phrases.map((text, i) => ({
x: i * 20,
y: i * 20,
dx: rand(0, 30) / 100,
dy: 0.5,
content: text,
animState.map((s) => ({
x: s.x,
y: s.y,
dx: s.dx,
dy: s.dy,
content: s.content,
})),
);
let rafId = 0;
let cachedCW = 0;
let cachedCH = 0;
function measureSizes() {
const c = container.value;
if (c) {
cachedCW = c.clientWidth;
cachedCH = c.clientHeight;
}
itemEls.value.forEach((el, i) => {
if (el && animState[i]) {
animState[i].cachedW = el.offsetWidth;
animState[i].cachedH = el.offsetHeight;
}
});
}
function animate() {
const c = container.value;
if (!c) return;
if (!cachedCW || !cachedCH) {
rafId = requestAnimationFrame(animate);
return;
}
const cw = c.clientWidth;
const ch = c.clientHeight;
items.value.forEach((item, i) => {
for (let i = 0; i < animState.length; i++) {
const s = animState[i];
const el = itemEls.value[i];
if (!el) return;
if (!el) continue;
const ew = el.offsetWidth;
const eh = el.offsetHeight;
s.x += s.dx;
s.y += s.dy;
item.x += item.dx;
item.y += item.dy;
if (s.x < 0 || s.x > cachedCW - s.cachedW) s.dx *= -1;
if (s.y < 0 || s.y > cachedCH - s.cachedH) s.dy *= -1;
if (item.x < 0 || item.x > cw - ew) item.dx *= -1;
if (item.y < 0 || item.y > ch - eh) item.dy *= -1;
});
el.style.transform = `translate(${s.x}px, ${s.y}px)`;
}
rafId = requestAnimationFrame(animate);
}
let resizeObserver: ResizeObserver;
onMounted(async () => {
await nextTick();
measureSizes();
rafId = requestAnimationFrame(animate);
resizeObserver = new ResizeObserver(measureSizes);
resizeObserver.observe(container.value!);
});
onUnmounted(() => {
cancelAnimationFrame(rafId);
resizeObserver?.disconnect();
});
</script>
@@ -79,9 +113,6 @@ onUnmounted(() => {
:key="i"
ref="itemEls"
class="absolute w-fit h-fit"
:style="{
transform: `translate(${item.x}px, ${item.y}px)`,
}"
>
<h1>
{{ item.content }}