Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/util/yield.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@ export function enqueueTask(callback: () => void): void {
// https://bugs.webkit.org/show_bug.cgi?id=327531.
// Without this workaround, async mode would be effectively sync inside a web worker in Safari.
// Instead, we very occasionally yield just so that really long-running async diffs will
// occasionally yield in Safari, while still eliminating 90% of the clamping in all environments.
// occasionally yield in Safari. That still eliminates 90% of the clamping where we have to fall
// back to setTimeout, and all of it where setImmediate exists.
if (++enqueueTaskCalls % 10 == 0) {
setTimeout(callback, 0);
// Use setImmediate which yields without 1ms minimum in runtimes where it exists, setTimeout
// as fallback
const setImmediate = (globalThis as any).setImmediate;
if (typeof setImmediate === 'function') {
setImmediate(callback);
} else {
setTimeout(callback, 0);
}
return;
}

Expand Down
9 changes: 7 additions & 2 deletions test/diff/character.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,17 @@ describe('diff/character', function() {
// other stuff to run - that is after all the point of async mode!
const oldText = 'ax'.repeat(1000);
const newText = 'ay'.repeat(1000);
// A 1ms interval should tick roughly once per millisecond while the diff runs. We compare
// against the elapsed time rather than a fixed count, since how long the diff takes depends
// on the machine.
const start = Date.now();
let ticks = 0;
const interval = setInterval(() => { ticks++; }, 1);
diffChars(oldText, newText, {callback: () => {
clearInterval(interval);
expect(ticks).to.be.at.least(100);
done();
const elapsed = Date.now() - start;
expect(ticks).to.be.at.least(elapsed / 2);
done();
}});
});
});
Expand Down