- Daishi Kato's Read the Code
- Posts
- Why Proxy Cache Is Important in Valtio
Why Proxy Cache Is Important in Valtio
Proxy Cache Is Based on WeakMap
Hi,
As we learned in an earlier post, creating a Proxy is as easy as this:
const p = new Proxy(target, handlers);
So, if we were to create a function to create a Proxy, it would look something like this:
function proxy(target) {
const handlers = { ... };
return new Proxy(target, handlers);
}
However, there is a slight problem with this approach depending on the use case. See the following behavior:
const obj = {};
const p1 = proxy(obj);
const p2 = proxy(obj);
console.log(p1 === p2); // ---> false
Since p1
and p2
are different Proxy instances, the comparison returns false
.
Using WeakMap to Cache Proxies
How can we fix this? This is where WeakMap
comes in.
const proxyCache = new WeakMap();
function proxy(target) {
if (proxyCache.has(target)) {
return proxyCache.get(target);
}
const handlers = { ... };
const p = new Proxy(target, handlers);
proxyCache.set(target, p);
return p;
}
As you can see, the created Proxy is stored in a WeakMap
, so it can be reused if the same target object is passed in again. This makes the previous example behave like this:
const obj = {};
const p1 = proxy(obj);
const p2 = proxy(obj);
console.log(p1 === p2); // ---> true
How Valtio Uses Proxy Cache
This is exactly how Valtio's proxy
works, although the actual implementation is more advanced. Valtio also supports nested proxies, where assigning a property automatically turns the assigned value into a proxy.
The behavior looks like this:
import { proxy } from 'valtio/vanilla';
const p = proxy({});
const obj = {};
p.a = obj;
p.b = obj;
console.log(p.a === p.b); // ---> true
// By the way
console.log(p.a === obj); // ---> false because p.a is a Proxy object
If you are curious about how this works, check out Valtio's source code to see how WeakMap
is used in practice:
Happy coding.
Reply