Lab · Live Regions

Streaming announcements, honestly modeled.

Text streams in token by token. The eye reads partial content comfortably; the spoken channel cannot. Every announcement strategy faces the same dilemma — interrupt and stammer, or queue and lag. This is the bench where strategies get measured against that dilemma, not a place where the “right” answer is shipped.

The strategies below are starting points — two that fail in instructive ways and one deliberately middling baseline — so you can see and hear how each handles the dilemma. This is an instrument for comparison, not a recommendation.

Active strategy

Villain 1. Cancels in-flight speech and re-announces the full buffer on every token. Always current, never intelligible.

Models the most common naive implementation: speechSynthesis.cancel() followed by a fresh speak() on every stream update.

Simulator controls

Panel A · Announcement timeline

What this is: a model of what the page hands the assistive technology — the announcement events and live-region mutations this page controls. What this is not: a record of what a screen reader actually says. No browser API exposes that.

Tokens in
0
Announce
0
Cancel
0
Flush
0

Tokens in (simulator)

    Events out (strategy)

      Panel B · Audio illustration

      What this is: the browser’s window.speechSynthesis reading the same event stream Panel A shows, so you can hear the contrast. What this is not: a screen reader. NVDA, JAWS, and VoiceOver each have their own queueing and interruption behavior; this is an illustration, not proof.

      Audio illustration is off.

      Fixture · the canned response

      Hand-curated to break naive strategies: multi-sentence prose, an em-dash, mid-word splits, a markdown list, and a fenced code block streamed symbol-by-symbol. Edit src/lib/lab/live-regions/fixture.ts to add cases.

      Streaming text is easy for the eye, hard for the ear. A sentence takes seconds to say — and in those seconds, more tokens arrive. Accessibility is the test case that makes the hardness visible.
      
      Three failure modes appear immediately:
      
      - Tokens arrive faster than speech.
      - Mid-word splits confuse phonetic parsers.
      - Code symbols get spoken individually.
      
      ```ts
      function announce(text: string): void {
        region.textContent = text;
      }
      ```
      
      That's the territory the lab is mapping.