Use a time-based limit to Terminal._innerWrite

The idea is that it should run for a bit and then let the renderer draw
a frame so that the terminal look responsive. The existing approach
limits the work done using a fixed number elements from the write
buffer so the duration of a frame can vary widely.

This approach looks at the clock to determine when to stop, we basically
allocate an amount of time each frame to write, while the rest can be
used for rendering.

From my tests this change makes the terminal feel a lot smoother.
This commit is contained in:
Juan Campa
2018-12-08 00:44:05 -05:00
parent b5f1c3384a
commit fd34caee23
+13 -7
View File
@@ -64,10 +64,12 @@ const document = (typeof window !== 'undefined') ? window.document : null;
const WRITE_BUFFER_PAUSE_THRESHOLD = 5;
/**
* The number of writes to perform in a single batch before allowing the
* renderer to catch up with a 0ms setTimeout.
* The max number of ms to spend on writes before allowing the renderer to
* catch up with a 0ms setTimeout. A value of < 33 to keep us close to
* 30fps, and a value of < 16 to try to run at 60fps. Of course, the real FPS
* depends on the time it takes for the renderer to draw the frame.
*/
const WRITE_BATCH_SIZE = 300;
const WRITE_TIMEOUT_MS = 12;
/**
* The set of options that only have an effect when set in the Terminal constructor.
@@ -1358,13 +1360,13 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
this.writeBuffer = [];
}
const writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);
while (writeBatch.length > 0) {
const data = writeBatch.shift();
const time = Date.now();
while (this.writeBuffer.length > 0) {
const data = this.writeBuffer.shift();
// If XOFF was sent in order to catch up with the pty process, resume it if
// the writeBuffer is empty to allow more data to come in.
if (this._xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {
if (this._xoffSentToCatchUp && this.writeBuffer.length === 0 && this.writeBuffer.length === 0) {
this.handler(C0.DC1);
this._xoffSentToCatchUp = false;
}
@@ -1382,6 +1384,10 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
this.updateRange(this.buffer.y);
this.refresh(this._refreshStart, this._refreshEnd);
if (Date.now() - time >= WRITE_TIMEOUT_MS) {
break;
}
}
if (this.writeBuffer.length > 0) {
// Allow renderer to catch up before processing the next batch