mcpField
B
bklit-studio-chart-performance

bklit-studio-chart-performance

github.com/bklit开发1.8k672 次安装今天更新
代码仓库

关于 bklit-studio-chart-performance

面向 bklit-ui 贡献者的图表性能优化 Skill,适用于 Studio 中交互卡顿的图表。它提供渲染隔离、静态 SVG 路径、上下文拆分和验证步骤。

主要功能

  1. 01定位交互引发的重复渲染
  2. 02拆分稳定数据与悬停状态
  3. 03完成进入动画后静态化路径
  4. 04缓存图表上下文与预览数据
  5. 05提供 Studio 性能验证清单

适用场景

  1. 01排查滑块操作导致的图表卡顿
  2. 02减少图例悬停时的重复计算
  3. 03优化画布平移期间的渲染
  4. 04发布前检查图表交互性能

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bklit/bklit-ui --skill bklit-studio-chart-performance

安装后在 Claude Code 中输入/bklit-studio-chart-performance确认已加载。

详细介绍

Studio 图表性能

当图表在 Studio 中显得卡顿,但类似图表(例如饼图)运行正常时使用。

一句话规则

如果需要入场动画,就保留路径上的入场动画,然后移除 Motion 路径订阅并隔离悬停状态,这样 Studio 滑块和图例更新就不会每帧都在所有系列上重复执行昂贵的弧线路径计算。


1. 找出每次交互都会重新渲染的内容

Studio 会在每次滑块刻度变化以及悬停图例/扇区时更新 displayState。追踪以下内容:

  • 悬停状态是否与数据、比例尺和动画配置位于同一个上下文中?
  • 预览是否会在每次渲染时重新创建子项(data.map、图案 defs、Motion props)?
  • 图表是否会不必要地重新挂载(key 关联的是 Motion 签名还是手动重播)?

模式:像笛卡尔图表/饼图那样拆分上下文——稳定切片(数据、几何信息、动画配置)与悬停切片(hoveredIndex、工具提示)。不需要悬停状态的使用者只使用稳定 hook(usePieStable、useRingStable、useChartStable 等)。

**Studio 平移:**将图表渲染包在 StudioChartRender(packages/studio/src/components/studio-chart-render.tsx)中,这样在渲染 props 未变化时,相机平移/FPS 计数器父组件的更新会跳过图表树。


2. 将 SVG 路径 d 动画视为高开销操作

使用 Motion / useTransform 与 d3 arc(或类似方案)对 d 添加动画时,每帧、每个系列都会运行布局和绘制。

优先选择避免
悬停时使用 transform / opacity(利于合成器处理)入场动画完成后持续进行 d 变形
入场动画结束后保持 d 静态图表整个生命周期都保留 d 上的 Motion 订阅
仅使用入场动画,之后保持路径静态因无关 prop 变化而重新运行入场路径计算

模式:使用 useMountProgress 实现入场动画 → 当进度 ≥ 1(useEnterComplete)时,渲染静态路径,并仅通过 motion.g 包装器上的 x/y/opacity/scale 为悬停添加动画(不要在 motion.path 上逐路径设置 scale)。

共享 hook:packages/ui/src/charts/use-enter-complete.ts


3. 对图表外壳上下文进行记忆化

未记忆化的 provider 值会迫使所有子项在每次父级渲染时都进行协调。

  • 使用显式依赖项(数据、弧线/半径、尺寸、回调)对稳定上下文对象进行记忆化。
  • 根据 hoveredIndex 和稳定的 setHoveredIndex 对悬停上下文进行记忆化(在图表外壳中使用 useCallback)。
  • 让 isLoaded 与环形/笛卡尔图表保持一致:使用 useEffect + timeout,而不是延迟的 useState 初始化器。

参考:pie-context.tsx、ring-context.tsx、chart-context.tsx、PieChartCore / RingChartCore 中 provider 值上的 useMemo。


4. 针对 Studio 预览的优化

与图表类型无关;应用于 packages/studio/src/components/charts/*-studio*.tsx:

优化方法
条件式 defs仅当某个系列使用图案时才传入 patternDefs / gradients
对派生数据进行记忆化彩色/映射后的数据数组;扇区/系列列表(useMemo,依赖项:dataSeed + 影响颜色的设计字段)
对入场 Motion 进行记忆化不要内联调用 getStudioMotionEnterProps;使用 useMemo,依赖项仅限 Motion 相关项(不要使用完整的 state)
对图例悬停进行记忆化在 useMemo 中使用 { hoveredIndex, setHoveredIndex }——已在 studio-legend-hover.tsx 中实现
对图表主体进行记忆化使用 memo() 包装器;传入基本类型值(chartKey、chartSize、data),而非整个 ctx,这样平移/外壳重新渲染时就会跳过重建
在 Studio 中禁用辉光在系列组件上设置 showGlow={false}

参考:pie-studio-preview.tsx、ring-studio-preview.tsx


5. 在 Studio 中与“快速”同类图表进行比较

将卡顿的图表与同一编辑器中操作流畅的图表(通常是 pie-chart)进行对比:

检查项卡顿的图表通常有流畅的图表通常有
外壳内联渲染、额外的定义StudioChartShell + 条件模式
系列数量大量动画路径更少的路径或更简单的几何形状
悬停Context + 整个树重新渲染稳定的订阅者;在 motion.g 上悬停 / 使用 translate
入场每个系列的路径 d 擦除动画入场后 d 静态;悬停时仅使用变换
平移每帧重建图表树StudioChartRender 记忆化边界

6. 验证标准

创建 PR 前:

pnpm lint
pnpm --filter @bklitui/ui check-types
pnpm --filter @bklitui/studio check-types
# scoped production build when touching studio/web

手动访问 /studio?chart=<slug>:

  • 入场动画
  • 悬停 / 图例同步
  • 拖动几何形状滑块(不必要时不重新挂载)
  • 入场后在画布上平移(按住空格键 + 拖动)——FPS 接近 pie-chart 基准
  • 支持时使用图案 / 渐变模式

图表状态(bklit-ui)

图表Slug状态
Piepie-chart✅ 参考(#120)
Ringring-chart✅ 符合检查清单(拆分 context、静态路径、StudioChartRender、预览记忆化)
Radar / Funnel / Choroplethvarious部分完成 — 运行检查清单
Cartesian / scatter / live-linevarious✅ #91 抽稀 + 悬停批处理
Sankeysankey-chart在链接描边上使用 useTransform — 可考虑使用 useEnterComplete
Gaugegauge-chart优先级较低(单个弧线)

关键文件

区域路径
入场完成钩子packages/ui/src/charts/use-enter-complete.ts
Pie 参考packages/ui/src/charts/pie-slice.tsx、pie-context.tsx、pie-studio-preview.tsx
Ringpackages/ui/src/charts/ring.tsx、ring-chart.tsx、ring-studio-preview.tsx
平移隔离packages/studio/src/components/studio-chart-render.tsx
注册表packages/studio/src/lib/registry.tsx

评论

支持 Markdown