Topics
v6.0.0
On this page · sections

JavaScript Proxy, Caching & Invalidation

Can you intercept operations with Proxy, and design a cache whose keys, lifetime, and eviction you can actually defend?

Proxy is the metaprogramming tool behind Vue 3 reactivity and some immutable libraries. Caching is a data-structure problem: correctness first, then memory.

LRU implementation is in LRU Cache. This page is when and why.

Questions

Proxy

  1. Proxy Traps and Reflect
  2. Invariants and Pitfalls

Caching

  1. Cache Keys and Invalidation
  2. Eviction vs Expiry

Senior-Level Follow-ups

  1. Why Vue 3 Uses Proxy
  2. In-Flight Deduplication
  3. Client Cache Is Not Security

Proxy

1. Proxy Traps and Reflect

Why This Matters

A Proxy wraps a target and intercepts operations: get, set, has, delete, apply, construct, …

Problem

How do you forward a trap without breaking invariants?

Example

const target = { n: 1 }; const proxy = new Proxy(target, { get(obj, prop, receiver) { return Reflect.get(obj, prop, receiver); }, set(obj, prop, value, receiver) { return Reflect.set(obj, prop, value, receiver); }, });

Reflect methods match the trap arguments and return the boolean/result the spec expects.

Using obj[prop] inside get can mishandle getters and prototypal this.

Interview Answer

“A Proxy intercepts operations on a target. I implement traps with Reflect.* so getters, this, and return values stay spec-correct. The proxy is a different object: === and WeakMap keys do not match the target unless I unwrap.”

2. Invariants and Pitfalls

Problem

What can a trap not lie about?

Example

If a property is non-writable and non-configurable on the target, get must return the actual value. set must report failure.

Revocable proxies:

const { proxy, revoke } = Proxy.revocable(target, handlers); revoke(); proxy.n; // TypeError

JSON.stringify, spread, and Object.keys hit traps. An expensive get will run often.

Do not Proxy every leaf in a giant tree without a need — that is allocation and trap overhead.

Interview Answer

“Traps cannot violate target invariants. I keep handlers small. I remember identity: the proxy is not the target. For libraries, I document whether users receive the proxy or the raw object.”

Caching

3. Cache Keys and Invalidation

Why This Matters

The hardest cache bug is serving the wrong value, not missing.

Problem

What makes a key stable, and when do you drop an entry?

Example

const key = `${url}?${userId}`;

Bad keys:

  • Stringifying objects ("[object Object]")
  • Omitting auth or locale
  • Using object identity when you meant structural equality

Invalidation strategies:

TTL → time Event → mutation / webhook / "user updated" Version → etag / updatedAt Manual → clear()

Stale-while-revalidate: serve old, refresh in background. Simple TTL: serve only if now < expiresAt.

Interview Answer

“A cache is keyed data with an invalidation policy. I put every dimension that changes the response into the key. I prefer explicit invalidation on writes plus a TTL safety net.”

4. Eviction vs Expiry

Problem

What is the difference between LRU and TTL?

Example

Eviction answers: which entry leaves when memory is full? LRU, LFU, FIFO.

Expiry answers: is this value still allowed? TTL.

A cache can need both: TTL for freshness, LRU for a capacity cap.

Lazy TTL (check on read) leaks write-only keys. Production caches add a sweep or a time-ordered queue.

undefined can be a stored value — use Map.has, not truthiness. Same rule as memoization.

Interview Answer

“TTL is about freshness. LRU is about capacity. I do not treat them as interchangeable. Lazy expiry is simple; I add a sweep if keys can go unread.”

Senior-Level Follow-ups

5. Why Vue 3 Uses Proxy

Vue 2 used defineProperty per key — could not detect new properties without Vue.set.

Proxy get/set/deleteProperty see new keys and deletions. Cost: Proxy identity, older-browser limits (already historical for Vue 3’s support window), and the need to unwrap in some APIs.

6. In-Flight Deduplication

Two components mounting together should not double-fetch the same URL.

Cache the Promise, not only the result. Assign it synchronously so concurrent callers share one in-flight request.

On reject, drop the Promise so the next call retries.

7. Client Cache Is Not Security

Browser LRU of API responses is UX. Authorization still happens on the server.

Private data in localStorage or an unbounded Map is a leak surface. Bound it, encrypt only if you have a real threat model, and prefer memory for tokens when the product allows.

Final Interview Strategy

1. Proxy + Reflect for correct forwarding 2. Respect invariants and identity 3. Cache keys include every variant 4. Invalidation is a policy, not a hope 5. LRU ≠ TTL 6. Deduplicate in-flight Promises 7. Client caches are not access control

Senior-level signal: For Proxy, talk spec traps and identity. For caches, talk key, lifetime, capacity, and failure — then the O(1) structure.

Last updated on