Skip to content

AI scenarios

Long conversations

Bit.BlazorUI.AI Scripted transport

Five hundred messages with code, tables, tool calls, and citations, rendered through a virtualized list.

Live demo

Scroll to the top and back, then send something: new content follows the view only while you are already at the bottom.

Five hundred messages

Question 221: what happens at scale here?

Answer 221. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.

Question 222: what happens at scale here?

Here is the shape of it:

csharp
var budget = TimeSpan.FromMilliseconds(18);
scheduler.Request();

The interval is the only dial that matters.

Question 223: what happens at scale here?
Searched the documentation
scale 444
  • Render modes 94%
  • Circuit lifetime 81%

Two passages matched, and they say the same thing.

Question 224: what happens at scale here?
MessagesRenderedNotes
60allbelow the threshold
500visible onlyvirtualized
Sources
1
Performance notes
Internal wiki
Question 225: what happens at scale here?

Answer 225. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.

Question 226: what happens at scale here?

Here is the shape of it:

csharp
var budget = TimeSpan.FromMilliseconds(26);
scheduler.Request();

The interval is the only dial that matters.

Question 227: what happens at scale here?
Searched the documentation
scale 452
  • Render modes 94%
  • Circuit lifetime 81%

Two passages matched, and they say the same thing.

Question 228: what happens at scale here?
MessagesRenderedNotes
60allbelow the threshold
500visible onlyvirtualized
Sources
1
Performance notes
Internal wiki
Question 229: what happens at scale here?

Answer 229. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.

Question 230: what happens at scale here?

Here is the shape of it:

csharp
var budget = TimeSpan.FromMilliseconds(34);
scheduler.Request();

The interval is the only dial that matters.

Question 231: what happens at scale here?
Searched the documentation
scale 460
  • Render modes 94%
  • Circuit lifetime 81%

Two passages matched, and they say the same thing.

Question 232: what happens at scale here?
MessagesRenderedNotes
60allbelow the threshold
500visible onlyvirtualized
Sources
1
Performance notes
Internal wiki
Question 233: what happens at scale here?

Answer 233. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.

Question 234: what happens at scale here?

Here is the shape of it:

csharp
var budget = TimeSpan.FromMilliseconds(42);
scheduler.Request();

The interval is the only dial that matters.

Question 235: what happens at scale here?
Searched the documentation
scale 468
  • Render modes 94%
  • Circuit lifetime 81%

Two passages matched, and they say the same thing.

Question 236: what happens at scale here?
MessagesRenderedNotes
60allbelow the threshold
500visible onlyvirtualized
Sources
1
Performance notes
Internal wiki
Question 237: what happens at scale here?

Answer 237. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.

Question 238: what happens at scale here?

Here is the shape of it:

csharp
var budget = TimeSpan.FromMilliseconds(50);
scheduler.Request();

The interval is the only dial that matters.

Question 239: what happens at scale here?
Searched the documentation
scale 476
  • Render modes 94%
  • Circuit lifetime 81%

Two passages matched, and they say the same thing.

Question 240: what happens at scale here?
MessagesRenderedNotes
60allbelow the threshold
500visible onlyvirtualized
Sources
1
Performance notes
Internal wiki
Question 241: what happens at scale here?

Answer 241. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.

Question 242: what happens at scale here?

Here is the shape of it:

csharp
var budget = TimeSpan.FromMilliseconds(18);
scheduler.Request();

The interval is the only dial that matters.

Question 243: what happens at scale here?
Searched the documentation
scale 484
  • Render modes 94%
  • Circuit lifetime 81%

Two passages matched, and they say the same thing.

Question 244: what happens at scale here?
MessagesRenderedNotes
60allbelow the threshold
500visible onlyvirtualized
Sources
1
Performance notes
Internal wiki
Question 245: what happens at scale here?

Answer 245. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.

Question 246: what happens at scale here?

Here is the shape of it:

csharp
var budget = TimeSpan.FromMilliseconds(26);
scheduler.Request();

The interval is the only dial that matters.

Question 247: what happens at scale here?
Searched the documentation
scale 492
  • Render modes 94%
  • Circuit lifetime 81%

Two passages matched, and they say the same thing.

Question 248: what happens at scale here?
MessagesRenderedNotes
60allbelow the threshold
500visible onlyvirtualized
Sources
1
Performance notes
Internal wiki
Question 249: what happens at scale here?

Answer 249. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.

Question 250: what happens at scale here?

Here is the shape of it:

csharp
var budget = TimeSpan.FromMilliseconds(34);
scheduler.Request();

The interval is the only dial that matters.

How it works

Up to a threshold every message is rendered, which is both simpler and faster. Past it (BitAiUiOptions.VirtualizeThreshold, sixty messages here) only the newest sixty are: scroll up and the older ones come in thirty at a time above what you are reading, which stays where it is, and once you are back at the newest message they are let go of again. Nothing is estimated - every message drawn is drawn at its own height - so the content never jumps and the view never goes blank. The conversation is deliberately varied - a thousand identical paragraphs would prove nothing; the hard case is mixed content with wildly different heights.

The five hundred messages are built in code (AiDemoConversations.Long) - a BitAiConversation filled with AddMessage, each answer a BitAiMessage of parts: text, Markdown, a tool call with its result, a table with a citation - and handed to the session factory (SessionFactory.Create(conversation)), so new messages go to the transport registered for the site, which echoes them. A conversation restored from storage is handed over the same way (see Conversations).

Where the render budget goes:

  • A part subscribes to itself, so a token re-renders the part it went into - not its message, nor the transcript. The chat around it renders as a turn starts and as it ends.
  • Each of those views renders at most once per 50 ms (BitAiUiOptions.RenderInterval), however many tokens arrive in that time - coalesced by a BitAiRenderScheduler, which an app's own component listening to a stream can use too (see Streaming).
  • Bursts of text are evened out before they reach the conversation: the session paces the deltas (BitAiChatSessionOptions.Pacing), so a paragraph arriving at once is drawn over a few frames rather than in one.
  • Text accumulates in a builder, so appending stays linear.
  • Markdown before the last block boundary is parsed once and reused.

Components used

  • BitAiMessageList - the transcript, drawing only its newest messages past the threshold, with auto-scroll that follows only a reader at the newest message.
  • BitAiScrollToLatest - the way back down once the reader has scrolled away.
  • BitAiMessagePartView - one part, re-rendered only when it changes.

Feedback

Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.