Performance: State machines with composables
This affects how efficiently the UI updates in response to state changes and how much unnecessary work the browser does during rendering.
import { createMachine, interpret } from '@xstate/fsm'; const machine = createMachine({ initial: 'idle', states: { idle: { on: { START: 'loading' } }, loading: { on: { FINISH: 'success' } }, success: {} } }); const service = interpret(machine).start(); const state = ref(service.state.value); service.onTransition(s => { state.value = s.value; });
const state = ref('idle'); function start() { state.value = 'loading'; } function finish() { state.value = 'success'; } // UI watches state and updates directly without clear transition rules
| Pattern | DOM Operations | Reflows | Paint Cost | Verdict |
|---|---|---|---|---|
| Direct state changes without machine | High (many updates) | Multiple reflows per state change | High paint cost due to redundant updates | [X] Bad |
| State machines with composables | Minimal (only on valid transitions) | Single reflow per transition | Lower paint cost due to fewer updates | [OK] Good |
ref is used to create a reactive primitive value like a string.reactive is for objects, computed is for derived values, and watch is for side effects, so they are incorrect here.state.value after calling next() twice?import { ref } from 'vue'
export function useMachine() {
const state = ref('idle')
function next() {
if (state.value === 'idle') state.value = 'loading'
else if (state.value === 'loading') state.value = 'success'
}
return { state, next }
}import { ref } from 'vue'
export function useMachine() {
const state = ref('idle')
function next() {
if (state === 'idle') state.value = 'loading'
else if (state.value === 'loading') state.value = 'success'
}
return { state, next }
}next() is called from 'loading'?state.value === 'loading' to set state.value = 'failure' extends the state machine correctly without removing existing transitions.else if (state.value === 'loading') state.value = 'failure' -> Option APass the test and this pattern moves unknown