Building a chat app seems easy: an input, a button, and a list. But once you have hundreds of messages, things get slow. The app might lag, scrolling becomes "janky," and your computer’s memory starts to cry.
To build something as smooth as WhatsApp or Discord, you need to understand how React handles thousands of items without breaking a sweat.
Why Chat Apps Get Slow
Most chat apps fail because of these common issues:
- Too many re-renders: Every time you type a letter, the whole message list refreshes.
- DOM Bloat: Trying to force the browser to draw 5,000 messages at once.
- Scroll Jumps: New messages arriving while you're trying to read old ones, causing the screen to bounce.
Strategy 1: The "Don't Repeat Yourself" Render
Our first line of defense is React.memo. This tells React: "If the message text hasn't changed, don't waste time redrawing it."
// components/Message.tsx
import React from 'react';
// Wrapping the component in React.memo is a huge performance win!
const Message = React.memo(({ sender, content, timestamp, isMine }) => {
const messageClass = isMine ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800';
return (
<div className={`p-2 my-1 rounded-lg ${messageClass}`}>
{!isMine && <span className="font-bold text-xs">{sender}: </span>}
<p className="text-sm">{content}</p>
<span className="block text-xs text-right opacity-50">{timestamp}</span>
</div>
);
});
export default Message;
Strategy 2: Smooth Scrolling with useLayoutEffect
There is a tiny difference between useEffect and useLayoutEffect.
-
useEffecthappens after the screen updates (can cause a visible flicker). -
useLayoutEffecthappens before the screen paints (perfect for fixing scroll positions silently).
The Chat Container Logic
// components/ChatContainer.tsx
import React, { useRef, useLayoutEffect, useState, useCallback } from 'react';
import Message from './Message';
const ChatContainer = () => {
const [messages, setMessages] = useState([]);
const chatScrollRef = useRef(null);
const [isScrolledUp, setIsScrolledUp] = useState(false);
// Keep the chat at the bottom, but only if the user isn't reading old messages
useLayoutEffect(() => {
const container = chatScrollRef.current;
if (container && !isScrolledUp) {
container.scrollTop = container.scrollHeight;
}
}, [messages, isScrolledUp]);
const handleScroll = () => {
const { scrollTop, scrollHeight, clientHeight } = chatScrollRef.current;
// Check if user has scrolled up away from the bottom
const isAtBottom = scrollHeight - scrollTop - clientHeight < 100;
setIsScrolledUp(!isAtBottom);
};
return (
<div className="flex flex-col h-screen p-4">
<div
ref={chatScrollRef}
onScroll={handleScroll}
className="flex-1 overflow-y-auto flex flex-col"
>
{messages.map((msg) => (
<Message key={msg.id} {...msg} />
))}
</div>
{isScrolledUp && (
<button className="fixed bottom-20 right-8 bg-blue-600 text-white p-2 rounded">
New Messages Below
</button>
)}
</div>
);
};
Pro-Tips for Success
1. The "Key" Rule
Never use the array index (0, 1, 2...) as a key prop. If a message is deleted or moved, React will get confused and slow down. Always use a unique ID from your database.
2. Don't Render Everything
If you have 10,000 messages, don't put them all in the DOM. Use Virtualization (libraries like react-window). This technique only renders the 10 or 20 messages that are actually visible on the screen.
3. Smart Updates
When adding a new message, don't "mutate" your state. Use the spread operator [...messages, newMessage] or a library like Immer. This helps React realize exactly what changed instantly.
Summary
A professional chat UI isn't just about looking good; it's about being "expensive-feeling"—fast, responsive, and smart. By using Memoization to save CPU cycles and Layout Effects to handle scrolling, you can build an interface that feels like a native app.
✨ Let's keep the conversation going!
If you found this interesting, I'd love for you to check out more of my work or just drop in to say hello.
✍️ Read more on my blog: bishoy-bishai.github.io
☕ Let's chat on LinkedIn: linkedin.com/in/bishoybishai
📘 Curious about AI?:
You can also check out my book:
Surrounded by AI
Top comments (0)