You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目使用ChartJS图表首屏加载异常、刷新重渲染闪烁问题求助

问题原因分析
  • 两个异步接口独立返回,任意一个请求完成更新state都会触发flatData执行,此时另一个接口还未返回,对应state是初始空值/undefined,处理后的数据异常就会出现undefined展示
  • 两个接口先后返回会触发两次flatData、两次图表渲染,两次渲染的间隙就是你看到的闪烁现象,50个图表的场景下重复渲染还会导致明显的性能损耗
解决方案

1. 加载遮罩与异常展示处理

新增加载状态统一控制渲染时机,加载完成前展示遮罩/骨架屏,避免异常内容暴露:

// 新增加载状态
const [isLoading, setIsLoading] = useState(true)

useEffect(() => {
  const fetchAllData = async () => {
    setIsLoading(true)
    try {
      // 并行请求两个接口,等全部返回再处理
      const [monthRes, productRes] = await Promise.all([
        http.get("/endpoint1"),
        http.get("/endpoint2")
      ])
      setEstimatedMonths(monthRes.data.data)
      setEstimatedProducts(productRes.data.data)
    } catch (e) {
      console.log("error", e)
    } finally {
      setIsLoading(false)
    }
  }
  fetchAllData()
}, [control])

// 渲染层逻辑示例
return (
  <div className="chart-container">
    {isLoading ? <div className="loading-mask">加载中...</div> : <ChartComponent data={values} />}
  </div>
)

2. 解决图表闪烁重复渲染问题

  • 采用上面的Promise.all统一处理请求,所有数据准备完成后才会触发一次flatData和图表渲染,从根源避免重复渲染
  • 新增Chart实例销毁逻辑,避免重复创建实例导致的渲染异常和内存泄漏:
// 提前用useRef存储chart实例
const chartInstance = useRef(null)

useLayoutEffect(() => {
  // 先销毁旧实例
  if(chartInstance.current) {
    chartInstance.current.destroy()
  }
  // 再创建新图表
  chartInstance.current = chart()
  return () => {
    // 组件卸载时销毁实例
    chartInstance.current?.destroy()
  }
}, [values])
排查验证方法
  • 在flatData、chart函数中添加日志,确认优化后是否仅触发1次
  • 打开浏览器性能面板录制刷新过程,确认图表对应的DOM节点是否仅重绘1次

内容的提问来源于stack exchange,提问作者zhyp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 09:18:02