Debounce mathjax rendering via cooldown instead (#4173)

* add cooldown timer

* debounce mathjax rendering via cooldown instead
This commit is contained in:
llama 2025-07-08 01:56:13 +08:00 committed by GitHub
parent 3d9fbfd97f
commit 11c3e60615
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 9 deletions

View file

@ -38,7 +38,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { pageTheme } from "$lib/sveltelib/theme";
import { convertMathjax, unescapeSomeEntities } from "./mathjax";
import { ChangeTimer } from "./change-timer";
import { CooldownTimer } from "./cooldown-timer";
export let mathjax: string;
export let block: boolean;
@ -46,25 +46,23 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let converted: string, title: string;
const debouncedMathjax = writable(mathjax);
const debouncer = new ChangeTimer();
$: debouncer.schedule(() => debouncedMathjax.set(mathjax), 500);
const debouncer = new CooldownTimer(500);
$: {
$: debouncer.schedule(() => {
const cache = getCache($pageTheme.isDark, fontSize);
const entry = cache.get($debouncedMathjax);
const entry = cache.get(mathjax);
if (entry) {
[converted, title] = entry;
} else {
const entry = convertMathjax(
unescapeSomeEntities($debouncedMathjax),
unescapeSomeEntities(mathjax),
$pageTheme.isDark,
fontSize,
);
[converted, title] = entry;
cache.set($debouncedMathjax, entry);
cache.set(mathjax, entry);
}
}
});
$: empty = title === "MathJax";
$: encoded = encodeURIComponent(converted);

View file

@ -0,0 +1,31 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export class CooldownTimer {
private executing = false;
private queuedAction: (() => void) | null = null;
private delay: number;
constructor(delayMs: number) {
this.delay = delayMs;
}
schedule(action: () => void): void {
if (this.executing) {
this.queuedAction = action;
} else {
this.executing = true;
action();
setTimeout(this.#pop.bind(this), this.delay);
}
}
#pop(): void {
this.executing = false;
if (this.queuedAction) {
const action = this.queuedAction;
this.queuedAction = null;
this.schedule(action);
}
}
}