Guides
Performance
Optimize chart rendering for large datasets and complex visualizations
vccs charts are reactive — they re-render when data or props change. For most use cases, performance is excellent out of the box. For large datasets or frequent updates, these tips help keep things smooth.
Use computed for derived data
Avoid computing data inline in templates. Use computed to cache derived values:
<script setup>
import { computed } from 'vue'
// Good: computed caches the result
const chartData = computed(() =>
rawData.value.map(d => ({ ...d, total: d.a + d.b }))
)
// Bad: recalculates every render
// :data="rawData.map(d => ({ ...d, total: d.a + d.b }))"
</script>
<template>
<LineChart :data="chartData">
<Line data-key="total" />
</LineChart>
</template>
Disable animations for large datasets
Animations run per-element. With thousands of data points, disable them:
<Line data-key="value" :is-animation-active="false" />
<Bar data-key="value" :is-animation-active="false" />
<Area data-key="value" :is-animation-active="false" />
Sample large datasets
Rather than rendering 10,000+ points, downsample your data:
<script setup>
import { computed } from 'vue'
const sampledData = computed(() => {
const data = rawData.value
if (data.length <= 500) return data
const step = Math.ceil(data.length / 500)
return data.filter((_, i) => i % step === 0)
})
</script>
Unwrap reactive proxies for D3
D3 scale functions don't work with Vue's reactive Proxy objects. Use toRaw() when passing data to D3:
<script setup>
import { toRaw } from 'vue'
// When working with custom scales or D3 utilities
const rawEntry = toRaw(entry)
</script>
This is handled internally by vccs, but keep it in mind if you're using D3 utilities directly alongside your charts.
Avoid unnecessary re-renders
- Stable data references: Don't create new arrays/objects on every render. Use
reforcomputedto maintain stable references. - Key prop: When dynamically switching between charts, use
:keyto control component identity and avoid stale state. - Debounce updates: If data changes rapidly (e.g., real-time feeds), debounce updates to avoid overwhelming the renderer.