fix(editor): improve result navigation and scrolling performance
This commit is contained in:
17 files changed
+392
-36
No files matched your search
@@ -0,0 +1,45 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { createDeferredEditorTask } from "@/lib/editor/deferredEditorTask";
|
||||
|
||||
afterEach(() => vi.useRealTimers());
|
||||
|
||||
describe("deferred editor work", () => {
|
||||
it("does no work during sustained scrolling and processes the final viewport once", () => {
|
||||
vi.useFakeTimers();
|
||||
let viewport = 0;
|
||||
const publish = vi.fn(() => viewport);
|
||||
const task = createDeferredEditorTask(publish, 150);
|
||||
for (let frame = 0; frame < 100; frame++) {
|
||||
viewport = frame * 20;
|
||||
task.schedule();
|
||||
vi.advanceTimersByTime(16);
|
||||
}
|
||||
expect(publish).not.toHaveBeenCalled();
|
||||
vi.advanceTimersByTime(150);
|
||||
expect(publish).toHaveBeenCalledOnce();
|
||||
expect(publish).toHaveReturnedWith(1980);
|
||||
});
|
||||
|
||||
it("flushes pending work before an owner switch without a later duplicate", () => {
|
||||
vi.useFakeTimers();
|
||||
let owner = "old-tab";
|
||||
const publish = vi.fn(() => owner);
|
||||
const task = createDeferredEditorTask(publish, 150);
|
||||
task.schedule();
|
||||
task.flush();
|
||||
owner = "new-tab";
|
||||
vi.runAllTimers();
|
||||
expect(publish).toHaveBeenCalledOnce();
|
||||
expect(publish).toHaveReturnedWith("old-tab");
|
||||
});
|
||||
|
||||
it("cancels semantic refreshes when the editor plugin is destroyed", () => {
|
||||
vi.useFakeTimers();
|
||||
const refresh = vi.fn();
|
||||
const task = createDeferredEditorTask(refresh, 100);
|
||||
task.schedule();
|
||||
task.cancel();
|
||||
vi.runAllTimers();
|
||||
expect(refresh).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
/** Keep nonvisual work off continuous typing/scrolling, with an explicit lifecycle flush. */
|
||||
export function createDeferredEditorTask(run: () => void, delay: number) {
|
||||
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||
function cancel() {
|
||||
if (timer !== null) clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
return {
|
||||
schedule() {
|
||||
cancel();
|
||||
timer = setTimeout(() => {
|
||||
timer = null;
|
||||
run();
|
||||
}, delay);
|
||||
},
|
||||
cancel,
|
||||
flush() {
|
||||
if (timer === null) return;
|
||||
cancel();
|
||||
run();
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user