From 7aef8e873dec3b3803d6ab26c765614e0d1d63d9 Mon Sep 17 00:00:00 2001 From: alikia2x Date: Tue, 4 Feb 2025 22:25:40 +0800 Subject: [PATCH] improve: performance, added a fps monitor panel --- bun.lockb | Bin 257772 -> 219052 bytes package.json | 3 +- packages/core/components/displayFPS.svelte | 135 ++++++++++++++++++ .../core/components/lyrics/lyricLine.svelte | 4 + .../core/components/lyrics/newLyrics.svelte | 81 ++++++++--- packages/core/package.json | 3 +- packages/web/package.json | 2 - .../web/src/routes/play/[id]/+page.svelte | 2 +- tsconfig.base.json | 3 +- 9 files changed, 203 insertions(+), 30 deletions(-) create mode 100644 packages/core/components/displayFPS.svelte diff --git a/bun.lockb b/bun.lockb index ef47415d565aa4f75428930241b265a4f081f7f7..9febfb2439add638a49b67f68561e6220c310590 100755 GIT binary patch delta 35149 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 K!w6^eng1XCN5KOC delta 57944 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 Y#7ta<-J##{V|}IgXAk(VTEF}M0Mx}l9RL6T diff --git a/package.json b/package.json index db822f6..d203dc2 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": false, "module": "index.ts", "type": "module", - "workspaces": ["packages/web", "packages/core", "packages/electron"], + "workspaces": ["packages/web", "packages/core"], "scripts": { "electron:dev": "bun --filter 'electron' dev", "web:dev": "bun --filter 'web' dev", @@ -37,7 +37,6 @@ "concurrently": "^9.0.1", "cross-env": "^7.0.3" }, - "dependencies": {}, "trustedDependencies": [ "svelte-preprocess" ] diff --git a/packages/core/components/displayFPS.svelte b/packages/core/components/displayFPS.svelte new file mode 100644 index 0000000..8ee6ca0 --- /dev/null +++ b/packages/core/components/displayFPS.svelte @@ -0,0 +1,135 @@ + + +

+ {fps} fps
+ Frame Time: {frameTime.toFixed(2)} ms
+ 1% Low: {onePercentLow} fps +

+fps + +frametime + diff --git a/packages/core/components/lyrics/lyricLine.svelte b/packages/core/components/lyrics/lyricLine.svelte index ed1684c..55317aa 100644 --- a/packages/core/components/lyrics/lyricLine.svelte +++ b/packages/core/components/lyrics/lyricLine.svelte @@ -38,6 +38,7 @@ let isCurrentLyric = false; function updateY(timestamp: number) { + if (stopped) return; if (lastUpdateY === undefined) { lastUpdateY = new Date().getTime(); } @@ -52,6 +53,7 @@ } function updateX(timestamp: number) { + if (stopped) return; if (lastUpdateX === undefined) { lastUpdateX = timestamp; } @@ -70,6 +72,7 @@ * @param {number} pos - X offset, in pixels */ export const setX = (pos: number) => { + stopped = true; positionX = pos; }; @@ -78,6 +81,7 @@ * @param {number} pos - Y offset, in pixels */ export const setY = (pos: number) => { + stopped = true; positionY = pos; }; diff --git a/packages/core/components/lyrics/newLyrics.svelte b/packages/core/components/lyrics/newLyrics.svelte index 55463a2..45d5644 100644 --- a/packages/core/components/lyrics/newLyrics.svelte +++ b/packages/core/components/lyrics/newLyrics.svelte @@ -4,6 +4,7 @@ import LyricLine from './lyricLine.svelte'; import createLyricsSearcher from '@core/lyrics/lyricSearcher'; import userAdjustingProgress from '@core/state/userAdjustingProgress'; + import DisplayFps from '../displayFPS.svelte'; // constants const viewportHeight = document.documentElement.clientHeight; @@ -16,11 +17,16 @@ document.body.style.overflow = 'hidden'; // Props - let { originalLyrics, progress, player, showInteractiveBox } : { - originalLyrics: LyricData, - progress: number, - player: HTMLAudioElement | null, - showInteractiveBox: boolean + let { + originalLyrics, + progress, + player, + showInteractiveBox + }: { + originalLyrics: LyricData; + progress: number; + player: HTMLAudioElement | null; + showInteractiveBox: boolean; } = $props(); // States @@ -76,15 +82,28 @@ for (let i = 0; i < lyricElements.length; i++) { const currentLyricComponent = lyricComponents[i]; const lyric = originalLyrics.scripts[i]; + const lyricBeforeProgress = lyric.end < progress; + const lyricInProgress = lyric.start <= progress && progress <= lyric.end; + const lyricWillHigherThanViewport = lyricTopList[i + 3] - relativeOrigin < 0; + const lyricWillLowerThanViewport = lyricTopList[i - 3] - relativeOrigin > lyricsContainer?.getBoundingClientRect().height!; + let delay = 0; - if (progress > lyric.end) { + if (lyricBeforeProgress) { delay = 0; - } else if (lyric.start <= progress && progress <= lyric.end) { - delay = 0.042; + } else if (lyricInProgress) { + delay = 0.03; } else { delay = Math.min(Math.min(currentLyricDuration, 0.6), 0.067 * (i - currentLyricIndex + 1.2)); } - currentLyricComponent.update({ x: 0, y: lyricTopList[i] - relativeOrigin }, delay); + + // if it's not in the viewport, we need to use animations + if (lyricWillHigherThanViewport || lyricWillLowerThanViewport) { + currentLyricComponent.update({ x: 0, y: lyricTopList[i] - relativeOrigin }, delay); + } + // if it's still in the viewport, we need to use spring animation + else { + currentLyricComponent.update({ x: 0, y: lyricTopList[i] - relativeOrigin }, delay); + } } } @@ -111,11 +130,16 @@ }); function handleScroll(deltaY: number) { + if (lyricComponents[0].getInfo().y > 0 && deltaY < 0) { + deltaY = 0; + } + if (lyricComponents[lyricComponents.length - 1].getInfo().y < 100 && deltaY > 0) { + deltaY = 0; + } for (let i = 0; i < lyricElements.length; i++) { const currentLyricComponent = lyricComponents[i]; const currentY = currentLyricComponent.getInfo().y; scrolling = true; - currentLyricComponent.stop(); currentLyricComponent.setY(currentY - deltaY); currentLyricComponent.syncSpringWithDelta(deltaY); } @@ -200,21 +224,19 @@ lastEventProgress = progress; if (!lyricChanged || scrolling) return; if (!lyricIndexDeltaTooBig && deltaInRange) { - console.log("Event: regular move"); + console.log('Event: regular move'); console.log(new Date().getTime(), lastSeekForward); computeLayout(); - } - else if ($userAdjustingProgress) { + } else if ($userAdjustingProgress) { if (deltaTooBig && lyricChanged) { - console.log("Event: seek forward"); + console.log('Event: seek forward'); seekForward(); } else if (deltaIsNegative && lyricChanged) { - console.log("Event: seek backward"); + console.log('Event: seek backward'); seekForward(); } - } - else { - console.log("Event: regular move"); + } else { + console.log('Event: regular move'); computeLayout(); } }); @@ -253,16 +275,23 @@ {#if debugMode} + right-0 font-mono" + > progress: {progress.toFixed(2)}, nextUpdate: {nextUpdate}, scrolling: {scrolling}, current: {currentLyricIndex}, uap: {$userAdjustingProgress} +
+ +
{/if} {#if originalLyrics && originalLyrics.scripts}
{#each lyricLines as lyric, i} - + {/each}
{/if} diff --git a/packages/core/package.json b/packages/core/package.json index a4831a4..9893000 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -27,13 +27,12 @@ }, "dependencies": { "@alikia/aqualyrics": "npm:@jsr/alikia__aqualyrics", - "@applemusic-like-lyrics/core": "^0.1.3", - "@applemusic-like-lyrics/lyric": "^0.2.2", "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@rollup/plugin-commonjs": "^28.0.1", "@rollup/plugin-node-resolve": "^15.3.0", "@types/bun": "^1.1.6", "bezier-easing": "^2.1.0", + "chart.js": "^4.4.7", "jotai": "^2.8.0", "jotai-svelte": "^0.0.2", "jss": "^10.10.0", diff --git a/packages/web/package.json b/packages/web/package.json index 5b613dd..f8f03ee 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -37,8 +37,6 @@ }, "dependencies": { "@alikia/aqualyrics": "npm:@jsr/alikia__aqualyrics", - "@applemusic-like-lyrics/core": "^0.1.3", - "@applemusic-like-lyrics/lyric": "^0.2.4", "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@rollup/plugin-commonjs": "^28.0.1", "@rollup/plugin-node-resolve": "^15.3.0", diff --git a/packages/web/src/routes/play/[id]/+page.svelte b/packages/web/src/routes/play/[id]/+page.svelte index 59ec353..0db0d20 100644 --- a/packages/web/src/routes/play/[id]/+page.svelte +++ b/packages/web/src/routes/play/[id]/+page.svelte @@ -209,7 +209,7 @@ if (audioPlayer === null) return; if ($userAdjustingProgress === false) currentProgress = audioPlayer.currentTime; progressBarRaw.set(audioPlayer.currentTime); - }, 50); + }, 20); } onMount(() => { diff --git a/tsconfig.base.json b/tsconfig.base.json index a768407..75dbf4d 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -13,7 +13,8 @@ "sourceMap": true, "strict": true, "types": ["bun"] - } + }, + "exclude": ["node_modules", "build", "dist", "tmp"] // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias // except $lib which is handled by https://kit.svelte.dev/docs/configuration#files //