When developing a React-based real-time chat application, we encountered a common but frustrating issue: as users moved their mouse between messages, the message bubbles and code blocks would noticeably jitter, affecting the user experience. This article shares how we diagnosed this problem and implemented performance optimizations to eliminate this visual defect.
问题分析
Problem Analysis
我们的聊天应用使用了以下关键组件:
Our chat application used these key components:
MessageItem - 渲染单条消息,包括文本、代码和图片
Renders individual messages, including text, code, and images
MarkdownContent - 解析和渲染消息内容中的 Markdown 格式
Parses and renders Markdown format in message content
CodeBlock - 处理代码块的语法高亮和复制功能
Handles syntax highlighting and copy functionality for code blocks
通过检查代码和细致地观察 UI 行为,我们发现了几个导致抖动的主要原因:
By examining the code and carefully observing UI behavior, we identified several main causes of the jitter:
1. 条件渲染导致的布局变化
1. Layout Changes from Conditional Rendering
消息组件在鼠标悬停状态改变时会显示或隐藏时间戳:
The message component would show or hide timestamps when hover state changed:
Besides solving the jitter issue, we discovered and fixed a problem with how the Markdown parser handled quote blocks. The parser treated all lines after a quote mark > as part of the quote. We solved this by adding a preprocessing function:
const fixQuoteBlocks = (content: string): string => { const lines = content.split('\n') const result: string[] = [] let i = 0 while (i < lines.length) { const line = lines[i] // 检测是否以 > 开头(考虑前导空格) // Detect if line starts with > (considering leading spaces) if (/^\s*>\s*/.test(line)) { // 添加当前引用行 | Add current quote line result.push(line) // 检查下一行是否也是引用 // Check if next line is also a quote if (i + 1 < lines.length && !/^\s*>\s*/.test(lines[i + 1]) && lines[i + 1].trim() !== '') { // 下一行不是引用且不是空行,添加空行以结束引用块 // Next line is not a quote and not empty, add empty line to end quote block result.push('') } } else { // 非引用行直接添加 | Add non-quote line directly result.push(line) } i++ } return result.join('\n')}
By implementing these optimizations, we successfully resolved the jitter issue with message bubbles and code blocks, significantly improving the user experience. From this process, we learned these key lessons:
Layout stability is crucial: Even tiny layout changes can cause noticeable visual jitter. Using fixed dimensions and stable positioning strategies can prevent this.
Preprocess content data: Preprocessing and caching complex data can avoid repeated computations, especially for content requiring parsing like Markdown.
These optimizations not only improved our application's performance but also enhanced the user experience, making the interface smoother and more professional. Through these small but effective improvements, we were able to build a responsive, visually stable frontend application.
适用场景
Applicable Scenarios
这些优化技术适用于:
These optimization techniques apply to:
实时聊天或消息应用
Real-time chat or messaging applications
具有复杂交互元素的内容展示系统
Content display systems with complex interactive elements
需要处理动态内容且要求视觉稳定性的界面
Interfaces that handle dynamic content and require visual stability
使用 Markdown 或其他富文本格式的应用
Applications using Markdown or other rich text formats
通过关注这些细节,我们能够创造出流畅、专业的用户体验,让用户在使用应用时感到舒适和愉悦。
By focusing on these details, we can create smooth, professional user experiences that make users feel comfortable and delighted when using our applications.