React渲染超大的字符串

javascript 复制代码
import React, { useState, useEffect, useRef } from 'react';

const BigTextViewer = ({ text, chunkSize = 10000 }) => {
  const [visibleChunks, setVisibleChunks] = useState([]);
  const [currentIndex, setCurrentIndex] = useState(0);
  const containerRef = useRef(null);

  useEffect(() => {
    if (currentIndex * chunkSize >= text.length) return;

    const renderNextChunk = () => {
      const start = currentIndex * chunkSize;
      const end = Math.min(start + chunkSize, text.length);
      const chunk = text.substring(start, end);

      setVisibleChunks((prev) => [...prev, chunk]);
      setCurrentIndex((prev) => prev + 1);
    };

    // 使用requestAnimationFrame进行分批渲染
    if (currentIndex < 100) {
      // 初始快速渲染
      requestAnimationFrame(renderNextChunk);
    } else {
      // 后续慢速渲染,避免阻塞
      setTimeout(renderNextChunk, 0);
    }
  }, [currentIndex, text, chunkSize]);

  return (
    <div ref={containerRef} className="min-h-full whitespace-pre-wrap p-4 border rounded">
      {visibleChunks.map((chunk, index) => (
        <span key={index}>{chunk}</span>
      ))}
    </div>
  );
};

export default BigTextViewer;

在 React 里把一个超大的字符串分块渲染出来,避免一次性渲染导致浏览器卡顿

拆解一下逻辑 👇


📌 主要思路

  1. 分块切割字符串

    • chunkSize(默认 10000 个字符)把大文本切成一段一段。
    • 每次只渲染一段,而不是整个文本。
  2. 逐步渲染

    • requestAnimationFrame 在前 100 个分块时快速渲染(保证用户很快看到内容)。
    • 超过 100 块后,改用 setTimeout(异步队列)继续加载,避免主线程被长时间占用。
  3. 状态管理

    • visibleChunks 存储已经渲染的字符串块。
    • currentIndex 记录当前渲染到第几块。
  4. 渲染输出

    • 每个 chunk 作为一个 <span> 渲染,最终拼接成完整的大文本。
    • whitespace-pre-wrap 让空格和换行格式保持不变。

📌 执行过程

  • 初始 currentIndex = 0
  • useEffect 检查是否还有没渲染的块 → 切下一块 → 更新状态 → currentIndex + 1
  • 组件重新渲染 → useEffect 再次运行 → 继续下一块
  • 循环直到所有 chunk 渲染完。

📌 使用场景

  • 大日志文件预览
  • 代码文件(几十 MB)在线展示
  • 逐步加载长文本(小说、爬虫抓取的长文章)

📌 优点

✅ 不会卡死页面(因为分批渲染)。

✅ 用户能很快看到前面的内容,而不是等完整数据。

✅ 可调 chunkSize 控制性能 vs 流畅度。


📌 局限

⚠️ 所有渲染出来的内容还是会一直留在 DOM 里,超大文本(几百 MB)会造成 DOM 数量过多,拖慢滚动性能。

👉 如果是这种情况,就得结合 虚拟列表react-window / react-virtualized)来做。


相关推荐
雪芽蓝域zzs9 小时前
第二十七节:进阶:路由权限控制 + 404 / 401 全局异常页面开发
前端·javascript·html
风骏时光牛马9 小时前
稳定性治理与疑难问题深度分析实践
前端
光影少年9 小时前
react navite 简单原生方法双向调用示例
javascript·react native·react.js
zzzzzz3109 小时前
react-bits:把“酷炫组件”放回 React 组件化的语境里看
javascript·react.js·动效
梦曦i18 小时前
@meng-xi/create-uni-app vs unibest:轻量脚手架与重型框架的定位之争
前端·uni-app
平头哥技术团队18 小时前
Day 10 | 工欲善其事:VS Code 配置与项目归档
android·开发语言·前端·javascript·html·交互
乌恩大侠18 小时前
GH200 新增 NVMe SSD 分区、格式化与挂载完整流程
运维·服务器·前端
yume_sibai18 小时前
Element Plus 数据展示组件完全指南(15个核心组件)
前端·javascript·vue.js
qiuhaipeng119 小时前
Claude code 升级后上下文长度变短问题
java·前端·数据库
zzz_236819 小时前
个人 AI 记忆如何跨工具复用:用 Markdown、索引和 Skill 搭一个可治理的记忆库
前端·人工智能·react.js·前端框架·agent·agent测评