vercel / vercel/hyper

RFC: Generate back-pressure to keep a steady framerate

Open
#3,339 0 comments 2 reactions 3 assignees View on GitHub

@juancampa is already working on this.

Since Dec 17, 2018.

🤔RFC
Dominant language
TypeScript
Stars
44.7k
Forks
3.6k
Avg merge
21m
Merged PRs (30d)
1

Description

Opening this RFC to hear everyone's thoughts and ideas

Problem

Renderer is slowed down and starts dropping frames when the pty emits a lot of data (say, by running yes)

To recap, the data pipeline in hyper works as follows:

  • node-pty emits the binary data coming from the OS (typically in chunks of 4k but could be more, e.g. 64k)
  • session.js listens and batches this data for a few ms to reduce IPC thrashing when there's a lot of output. 1️⃣
  • app/rpc.js sends the batched data to the renderer process (as "session data")
  • lib/utils/rpc.js receives the data in the renderer process and emits a "session data" event
  • lib/index dispatches a redux action with the data
  • lib/store/write-middleware.js sends the data to the xterm.js Terminal instance
  • Terminal stores it in the writeBuffer (an array of strings) and starts parsing (asynchronously)
  • Terminal takes every chunk and parses it completely 2️⃣ (this is the most CPU intensive part and the current bottleneck)

(feel free to correct me if there's something inaccurate)

Proposed solution

In 2️⃣, keep track of how long it's taking to process each byte and determine how long each chunk should be so as to spend less than, say, 16ms (60fps here) parsing it. Then use this value either at 1️⃣ or at 2️⃣ to make sure chunks are not oversized.

Of course, as pointed out by @jerch, we must also account for GC and rendering, so the actual time should be less than 16ms.

I'm leaning heavily towards 2️⃣ because it keeps the splitting logic close to where the back-pressure is generated (implemented in xterm.js)

Caveats

It's very hard to *guarantee a specific FPS just by looking at chunk size because not all bytes have the same cost (e.g. newlines are way more expensive than printable characters)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.