Direct Answer
No, there are no documented benchmarks proving useVuetify() introduces measurable performance regression versus Vuetify 2 mixins in 100+ component applications. The composable is the officially recommended pattern, and any overhead depends on how you access reactive properties—not the composable itself.
Confirmed Facts
useVuetify() returns a reactive proxy to the Vuetify instance (theme, icons, locale, breakpoint, etc.).- Vue 3's reactivity system tracks dependencies per property access. Reading
vuetify.theme.global.name.value creates a subscription; reading vuetify.theme.global.name (the ref) does not. - Vuetify 2 mixins merged options once at component initialization. The Composition API equivalent resolves the instance once per
setup() call—also once per component. - The Vuetify team has not published comparative benchmarks for mixin vs. composable resolution.
Where Overhead Actually Appears
Performance differences emerge from usage patterns, not the composable call:
- Destructuring reactive properties:
const { theme } = useVuetify() is fine. const { global: { name } } = useVuetify().theme loses reactivity. const name = useVuetify().theme.global.name.value in a hot loop creates many subscriptions. - Template access depth:
{{ $vuetify.theme.global.name }} (Vuetify 2) vs {{ vuetify.theme.global.name.value }} (Vuetify 3) compile to similar proxy accesses. The difference is negligible. - Computed vs. direct access: Wrapping theme values in
computed() adds a dependency node. In 100+ components, prefer direct .value reads in templates or toRef() for passed props.
Practical Verification Steps
Run these in your actual application—not a synthetic benchmark:
- Profile with Vue DevTools: Open the Performance tab, record a typical user flow, and check "Component Render" durations. Filter for components calling
useVuetify(). - Count reactive dependencies: In the Components tab, select a component using
useVuetify() and inspect "Reactive Dependencies." Each unique property access (e.g., theme.global.name.value, icons.values.mdiHome) adds one. - Compare baselines: Temporarily replace
useVuetify().theme.global.name.value with a plain ref('light') in 10 high-frequency components. Re-profile. If render time drops >5%, reactivity tracking is the bottleneck.
Recommended Pattern for Scale
// composables/useVuetifyTheme.js
import { useVuetify } from 'vuetify'
import { computed } from 'vue'
export function useVuetifyTheme() {
const vuetify = useVuetify()
// Single subscription per component, not per property
const theme = computed(() => vuetify.theme.global.name.value)
const isDark = computed(() => vuetify.theme.global.current.value.dark)
return { theme, isDark }
}
This centralizes reactivity tracking and makes dependency counts predictable.
One Diagnostic Detail Needed
Are your 100+ components simultaneously mounted (e.g., virtualized lists, mega-menus) or lazily loaded? Simultaneous mounts amplify any per-component subscription cost; lazy loading amortizes it. This changes whether you should optimize useVuetify() calls or focus on mount-order scheduling.