Performance
iGaming UIs face unique performance challenges: frequent updates, large lists, complex animations. Here's how Fortune Kit handles them.
Animation Performance
RequestAnimationFrame
All animations use requestAnimationFrame for smooth 60fps:
ts
// Inside useWheel composable
function animate() {
if (!isSpinning.value) return
currentRotation.value += velocity
velocity *= friction
if (velocity > 0.1) {
requestAnimationFrame(animate)
} else {
onSpinComplete()
}
}CSS Transforms
Components use transform and opacity for GPU-accelerated animations:
css
.fk-wheel {
/* ✅ GPU accelerated */
transform: rotate(var(--rotation));
will-change: transform;
}
/* ❌ Avoid layout-triggering properties */
.bad {
left: 100px; /* Triggers layout */
}Reduced Motion
All components respect prefers-reduced-motion:
css
@media (prefers-reduced-motion: reduce) {
.fk-wheel {
transition: none;
}
}List Performance
FkLeaderboard
Optimized for large datasets:
- Virtual scrolling — Only renders visible items (coming in v1.1)
- Stable keys — Uses
entry.idfor efficient reconciliation - Memoized rows — Row components are pure
vue
<FkLeaderboard
:entries="players"
:max-visible="50" <!-- Pagination ready -->
/>Update Batching
For real-time leaderboards, batch updates to avoid layout thrashing:
ts
// ❌ Bad - updates DOM on every message
socket.on('score', (data) => {
entries.value.push(data)
})
// ✅ Good - batches updates
const pending = []
socket.on('score', (data) => pending.push(data))
setInterval(() => {
if (pending.length) {
entries.value = [...entries.value, ...pending.splice(0)]
}
}, 100)Bundle Size
Tree Shaking
Only import what you need:
ts
// ~2KB gzipped
import { FkResultWin } from '@fortune-kit/components'
// ~500B gzipped
import { useWheel } from '@fortune-kit/headless'
// ~300B gzipped
import { colors } from '@fortune-kit/tokens'Code Splitting
Lazy load heavy components:
ts
const FkWheel = defineAsyncComponent(() =>
import('@fortune-kit/components').then(m => m.FkWheel)
)Benchmarks
| Scenario | Target | Actual |
|---|---|---|
| Leaderboard render (100 items) | < 16ms | ~8ms |
| Wheel spin start | < 50ms | ~12ms |
| Token CSS parse | < 5ms | ~2ms |
Measured on M1 MacBook Air, Chrome 120, Vue 3.5.