Bklit Studio Chart Performance

bklit/bklit-ui/.agents/skills/bklit-studio-chart-performance

作者 bklit5d699897b2dde26374cf15501dbaadbc52cea982無授權條款1.7K 個星標收錄於 2026年10月9日更新於 2026年10月9日儲存庫13 天前更新

Reusable Studio chart performance audit and fix workflow. Use when a chart feels sluggish in /studio (pan, slider ticks, legend hover) but siblings like pie-chart feel fine.

AI 產生的概覽

稽核並修復 Studio 圖表卡頓問題,透過移除 Motion 路徑訂閱並隔離懸停更新來提升效能。

功能
提供一套逐步工作流程,用來診斷為何某個圖表在 Studio 中顯得卡頓,而類似圖表卻很順暢。內容涵蓋追蹤滑桿刻度與圖例懸停時的重繪、拆分穩定情境與懸停情境、以 transform 和 opacity 取代持續的 SVG 路徑 d 動畫、對圖表外殼情境進行記憶化,以及套用 Studio 預覽最佳化。最後提供驗證清單與圖表狀態表。
適用情境
當 /studio 中的某個圖表在平移、滑桿刻度或圖例懸停時顯得卡頓,而 pie-chart 等同类圖表卻正常時使用。對象為維護 bklit-ui 圖表函式庫與 Studio 預覽的開發者。
執行需求
需要搭配 pnpm 的 bklit-ui 單一儲存庫,以及所引用的套件(packages/ui、packages/studio)。驗證指令包括 pnpm lint 與 pnpm --filter check-types。此技能不附帶指令碼,僅為說明文件。

Studio chart performance

Use when a chart feels sluggish in Studio but similar charts (e.g. pie-chart) are fine.

One-line rule

Keep enter animation on paths if you need it, then drop Motion path subscriptions and isolate hover so Studio slider and legend updates don't replay expensive arc/path math across every series every frame.


1. Find what re-renders on every interaction

Studio updates displayState on every slider tick and on legend/slice hover. Trace:

  • Does hover live in the same context as data, scales, and animation config?
  • Does the preview recreate children (data.map, pattern defs, motion props) every render?
  • Does the chart remount unnecessarily (key tied to motion signature vs manual replay)?

Pattern: Split context like cartesian / pie charts — stable slice (data, geometry, animation config) vs hover slice (hoveredIndex, tooltip). Consumers that don't need hover use only the stable hook (usePieStable, useRingStable, useChartStable, …).

Studio pan: Wrap chart render in StudioChartRender (packages/studio/src/components/studio-chart-render.tsx) so camera pan / FPS counter parent updates skip the chart tree when render props are unchanged.


2. Treat SVG path d animation as expensive

Animating d with Motion / useTransform + d3 arc (or similar) runs layout + paint every frame, per series.

PreferAvoid
transform / opacity for hover (compositor-friendly)Continuous d morphing after enter is done
Static d once enter finishesKeeping Motion subscriptions on d for the chart's lifetime
Enter animation only, then static pathsRe-running enter path math on unrelated prop changes

Pattern: useMountProgress for enter → when progress ≥ 1 (useEnterComplete), render static paths and only animate hover with x/y/opacity/scale on a motion.g wrapper (not per-path scale on motion.path).

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


3. Memoize chart shell context

Unmemoized provider values force all children to reconcile on every parent render.

  • Memoize the stable context object with explicit deps (data, arcs/radii, dimensions, callbacks).
  • Memoize hover context on hoveredIndex + stable setHoveredIndex (useCallback in chart shell).
  • Match isLoaded to ring/cartesian: useEffect + timeout, not a lazy useState initializer.

Reference: pie-context.tsx, ring-context.tsx, chart-context.tsx, PieChartCore / RingChartCore useMemo on provider value.


4. Studio preview–specific wins

Chart-agnostic; apply in packages/studio/src/components/charts/*-studio*.tsx:

WinHow
Conditional defsOnly pass patternDefs / gradients when a series uses patterns
Memo derived dataColored/mapped data arrays; slice/series lists (useMemo, deps: dataSeed + design fields that affect color)
Memo motion enterDon't call getStudioMotionEnterProps inline; useMemo with motion-only deps (not full state)
Memo legend hover{ hoveredIndex, setHoveredIndex } in useMemo — already in studio-legend-hover.tsx
Memo chart bodymemo() wrapper; pass primitives (chartKey, chartSize, data) not whole ctx so pan/shell re-renders skip rebuild
Disable glow in StudioshowGlow={false} on series components

Reference: pie-studio-preview.tsx, ring-studio-preview.tsx


5. Compare against a “fast” sibling in Studio

Diff the slow chart against one that feels smooth in the same editor (usually pie-chart):

CheckSlow chart often hasFast chart often has
ShellInline render, extra defsStudioChartShell + conditional patterns
Series countMany animated pathsFewer paths or simpler geometry
HoverContext + full tree re-renderStable subscribers; hover on motion.g / translate
EnterPath d wipe per seriesStatic d after enter; transform-only hover
PanChart tree rebuilds every frameStudioChartRender memo boundary

6. Validation bar

Before opening a PR:

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

Manual /studio?chart=<slug>:

  • Enter animation
  • Hover / legend sync
  • Drag geometry sliders (no unnecessary remount)
  • Canvas pan (space + drag) after enter — FPS near pie-chart baseline
  • Pattern/gradient mode if supported

Chart status (bklit-ui)

ChartSlugStatus
Piepie-chart✅ Reference (#120)
Ringring-chart✅ Aligned to checklist (context split, static paths, StudioChartRender, preview memo)
Radar / Funnel / ChoroplethvariousPartial — run checklist
Cartesian / scatter / live-linevarious✅ #91 decimation + hover batching
Sankeysankey-chartuseTransform on link stroke — candidate for useEnterComplete
Gaugegauge-chartLow priority (single arc)

Key files

AreaPath
Enter-complete hookpackages/ui/src/charts/use-enter-complete.ts
Pie referencepackages/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
Pan isolationpackages/studio/src/components/studio-chart-render.tsx
Registrypackages/studio/src/lib/registry.tsx

來源與署名

來源:bklit/bklit-ui位於.agents/skills/bklit-studio-chart-performance提交5d69989

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架