Conversations can have thousands of messages.
Challenges:
- Variable height messages (text length, media)
- Scroll anchoring (stay at position when loading older)
- Bidirectional loading (older above, newer below)
Virtualization approach:
- Render only visible messages plus buffer
- Measure heights dynamically
- Cache heights after measurement
Scroll anchoring:
// Before loading older messages
const scrollHeight = container.scrollHeight;
// After loading
container.scrollTop += container.scrollHeight - scrollHeight;