All quizzesHard
Performance Internals — Series 2
Preview — 3 of 10 questions
A function receives a large plain object over a WebSocket and needs to mutate dozens of its nested fields before the UI reacts. Why does this pattern outperform storing the object in a deep reactive()?
javascript
import { shallowRef, triggerRef } from 'vue'
const snapshot = shallowRef(buildInitialSnapshot())
function applyPatch(patch) {
const raw = snapshot.value
for (const [path, value] of patch.entries) {
setNestedValue(raw, path, value) // dozens of in-place mutations
}
triggerRef(snapshot) // notify subscribers exactly once, after all mutations
}AshallowRef only tracks reactivity on .value reassignment, not on mutations to nested properties inside the object it holds — so the dozens of in-place field mutations trigger nothing on their own, and triggerRef(snapshot) is what manually notifies subscribers exactly once after the whole batch of mutations completes, instead of a deep reactive() firing a separate trigger for every single nested field write
BshallowRef makes .value itself non-reactive, so triggerRef() is only cosmetic and can be omitted with no observable difference
CtriggerRef() is required syntax any time shallowRef is used — without it, reading .value throws
DshallowRef and triggerRef() together disable reactivity entirely for snapshot, turning it into a plain mutable variable with no subscribers at all
A tabbed interface wraps its content in <KeepAlive :max="3">. The user visits 5 different tabs in sequence, then returns to the very first tab. What happens?
javascript
<template>
<KeepAlive :max="3">
<component :is="activeTabComponent" />
</KeepAlive>
</template>Amax="3" is silently ignored for dynamically-switched components — all 5 tab instances stay cached regardless
B<KeepAlive> caches at most 3 component instances at a time; once a 4th is cached, the least recently used instance is evicted (destroyed) — so by the time the user reaches the 5th tab, the first tab's instance has already been evicted and destroyed, meaning returning to it mounts a fresh instance instead of reactivating the cached one
Cmax="3" caps how many times a single component instance can be reactivated before it's forcibly destroyed, not how many distinct instances are cached
DExceeding max throws a runtime warning but keeps all instances cached anyway — max is purely advisory
A component mounts one row component per item in a 2,000-item list, and each rows `setup()` calls `watch(() => props.item.status, ...)`. Whats the expert-tier concern with this pattern at scale?
javascript
// inside each row's setup()
watch(() => props.item.status, (status) => {
syncStatusIndicator(status)
})Awatch() cannot be called inside a component that's rendered via v-for — Vue throws at mount time
BPer-row watchers are strictly more efficient than a shared parent-level watcher, because each one only re-runs for its own item's changes instead of the whole list
CEach mounted row creates and registers its own independent reactive effect with Vue's dependency-tracking system; with 2,000 rows that's 2,000 live watchers, each consuming memory and each re-evaluated on its own schedule — for a list this large, a single watch (or computed) at the parent level, keyed by item, or driving the same logic off one shared reactive derivation, scales far better than one effect per row
Dwatch() calls inside child components are automatically deduplicated by Vue into a single shared effect behind the scenes, so this pattern has no actual per-row cost
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.