feelsfast.fyi
Back

Chat Input

2 min read

The user types into a chat composer. The input must echo inside the perceptual frame Card-Moran-Newell Card, Moran & Newell 1983 describe — anything the input does that blocks for more than 50 ms (typeahead suggestions, mention parsing, markdown preview) puts the user in the same active-mode trap search-as-you-type covers.

The reuse-affinity is high: a chat composer is a search input plus a send button. Eizenberg's Eizenberg production-surface argument is the same here — every perception trick must protect the input itself, not paper over it.

Incremental Search

Same dataset, same filter logic, same artificial work per keystroke. The naive side blocks input on every keystroke; the tuned side uses React 19's useDeferredValue to keep the input instant while the filter catches up.

0 – 100 MS
Interactive

Off

38 results

  • Apple
  • Apricot
  • Avocado
  • Banana
  • Blackberry
  • Blueberry
  • Cherry
  • Coconut
  • Cranberry
  • Date
  • Dragon fruit
  • Elderberry
  • Fig
  • Grape
  • Grapefruit
  • Guava
  • Honeydew
  • Kiwi
  • Kumquat
  • Lemon
  • Lime
  • Lychee
  • Mango
  • Mulberry
  • Nectarine
  • Orange
  • Papaya
  • Passion fruit
  • Peach
  • Pear
  • Persimmon
  • Pineapple
  • Plum
  • Pomegranate
  • Raspberry
  • Strawberry
  • Tangerine
  • Watermelon

On

38 results

  • Apple
  • Apricot
  • Avocado
  • Banana
  • Blackberry
  • Blueberry
  • Cherry
  • Coconut
  • Cranberry
  • Date
  • Dragon fruit
  • Elderberry
  • Fig
  • Grape
  • Grapefruit
  • Guava
  • Honeydew
  • Kiwi
  • Kumquat
  • Lemon
  • Lime
  • Lychee
  • Mango
  • Mulberry
  • Nectarine
  • Orange
  • Papaya
  • Passion fruit
  • Peach
  • Pear
  • Persimmon
  • Pineapple
  • Plum
  • Pomegranate
  • Raspberry
  • Strawberry
  • Tangerine
  • Watermelon

What is happening

Same demo as search-as-you-type, framed for the chat case. Naive: synchronous work on every keystroke blocks the input. Tuned: useDeferredValue keeps the input live while the work happens at low priority. Whether the work is "filter a list" or "render markdown preview" or "parse @mentions," the structural answer is the same.

For the send button itself, pair this with optimistic-actions: on Send, render the user's message in the conversation immediately; stream the assistant response in parallel.

What to tune

  1. Keystroke echo — character renders inside ~50 ms. Anything that blocks the input (markdown parse, mention lookup) runs at low priority via useDeferredValue.
  2. In-flight side work — markdown preview, mention suggestions, autocomplete all run stale-while-revalidate. The input never waits on them.
  3. Send press — pre-action feedback within ~50 ms; the button echoes regardless of how long the message takes to commit.
  4. Optimistic commit — render the user's message in the conversation immediately on Send; clear the composer; let the assistant response stream in parallel.
  5. Completion — focus returns to the (now-empty) input so the user can keep typing.

When perceived performance hurts you here

Composer surfaces are pure production. A skeleton over the textarea, a spinner over the send button, a "thinking" placeholder where the user is typing — all wrong. Miller 1968's Miller 1968 keystroke-echo tier is unforgiving: if the input lags, no perception trick saves it.

Accessibility

  1. Don't lose focus on send. After the message commits, focus returns to the (now-empty) input so the user can keep typing.
  2. aria-multiline="true" on textareas; let the browser handle line breaks correctly.
  3. prefers-reduced-motion for any markdown preview animations.
  4. Keyboard send convention — Enter to send, Shift+Enter for newline. Document it visibly the first few times.

Other patterns that fit

Same band, same surface — switch in whichever maps best to your UI.

Mousedown vs. Click Head-start

Same button, same work. Naive: fires on `click` (after the user releases the mouse). Tuned: fires on `mousedown` (the moment the press begins). The user holds the button down for ~100–150 ms — that whole window is free latency budget you reclaim by starting work earlier.

0–100 MS
Interactive

Off

Press the button. Hold a beat before releasing.

On

Press the button. Hold a beat before releasing.

Optimistic State Update

Click the heart. Naive: button waits for the server, the count updates only after the round-trip. Tuned: optimistic flip, background commit, visible rollback on the rare failure (~10 %).

0–100 MS
Interactive

Off

On

References · 3

  1. Card, Moran & Newell 1983

    Card, S. K., Moran, T. P., & Newell, A. (1983). The Psychology of Human-Computer Interaction. Lawrence Erlbaum. ~100 ms perceptual frame; the input must echo inside it on every keystroke.

  2. Miller 1968

    Miller, R. B. (1968). Response time in man-computer conversational transactions. Proceedings of the AFIPS Fall Joint Computer Conference, 33(I), 267–277. The keystroke-echo tier (~0.1 s).

  3. Eizenberg

    Eizenberg, E. When Actual Performance Is More Important Than Perceived Performance (Medium). Chat composers are production surfaces — perception over real responsiveness is a tax.