tui: only check for emojis in visibleWidth when necessary

The initial render of a session, and any re-draws caused by terminal
resizing are noticeably slow, especially on conversations with 20+
turns and many tool calls.

From profiling with `bun --cpu-prof` (available since bun 1.3.2), the
majority of the rendering (90%) is spent on detection of emojis in the
string-width library, running the expensive `/\p{RGI_Emoji}$/v`
regular expression on every individual grapheme cluster in the entire
scrollback. I believe it essentially expands to a fixed search against
every possible emoji sequence, hence the amount of CPU time spent in it.

This change replaces the `stringWidth` from string-width with a
`graphemeWidth` function that performs a similar check, but avoids
running the `/\p{RGI_Emoji}$/v` regex for emoji detection unless it
contains codepoints that could be emojis.

The `visibleWidth` function also has two more optimisations:
- Short-circuits string length detection for strings that are entirely
  printable ASCII characters
- Adds a cache for non-ASCII segments to avoid recomputing string length
  when resizing
This commit is contained in:
nathyong 2025-12-30 16:40:06 +11:00 committed by Mario Zechner
parent 02175d908b
commit 6e4270a286
4 changed files with 130 additions and 34 deletions

View file

@ -38,9 +38,9 @@
"dependencies": {
"@types/mime-types": "^2.1.4",
"chalk": "^5.5.0",
"get-east-asian-width": "^1.3.0",
"marked": "^15.0.12",
"mime-types": "^3.0.1",
"string-width": "^8.1.0"
"mime-types": "^3.0.1"
},
"devDependencies": {
"@xterm/headless": "^5.5.0",