bklit/bklit-ui

bklit-studio-chart-performance

Reusable Studio chart performance audit and fix workflow.

View source

How to use

  1. Copy the installation command and review the source package before installing it in your own agent environment.
  2. Check the source document for required tools, credentials and supported hosts.
  3. Describe your input and desired deliverable; review the output against the source material.
npx skills add https://github.com/bklit/bklit-ui --skill bklit-studio-chart-performance

Before you start

  • Installation does not include a model subscription, API allowance or permission to access your files.
  • Repository stars and installation counts describe activity, not an independent quality or security test.
Original skill document

Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.

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 lint
pnpm --filter @bklitui/ui check-types
pnpm --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

Related by task

from this repository

More skills

All skills
bklit
Community

bklit-playground

DEPRECATED — use bklit-studio instead. Local /playground is no longer the chart development workflow for bklit-ui contributors.

installs
1
GitHub stars
1.8K
Updated
Oct 19
bklit
Community

bklit-studio

bklit-ui monorepo contributors only. Use automatically when building or editing charts, tuning props/animation, or prototyping in Studio (/studio). Replaces the deprecated local /playground route.

installs
1
GitHub stars
1.8K
Updated
Oct 19
bklit
Community

bklit-ui-design

Turns plain-language chart design requests into exact Bklit UI (@bklit shadcn registry) components and props, styled to fit the host app. Use when someone describes how a chart should look rather than naming props, e.g. "diagonal pattern background that fades out", "squircle bars", "3D glass bars", "hatched area", "dot grid", "skeleton loading state", "dashed forecast", "half donut", "make the charts match my brand / dark mode / border radius". Detects the project's Tailwind version, colour form

installs
1
GitHub stars
1.8K
Updated
Oct 19
bklit
Community

turborepo

Turborepo monorepo build system guidance. Triggers on: turbo.json, task pipelines, dependsOn, caching, remote cache, the "turbo" CLI, --filter, --affected, CI optimization, environment variables, internal packages, monorepo structure/best practices, and boundaries. Use when user: configures tasks/workflows/pipelines, creates packages, sets up monorepo, shares code between apps, runs changed/affected packages, debugs cache, or has apps/packages directories.

installs
1
GitHub stars
1.8K
Updated
Oct 19