Recently I've been abusing WeakMap
to solve performance issues in Javascript.
The WeakMap
work in a very similar way to its stronger brother Map
. You provide a key and a value. Whenever you need to retrieve the value for that key, you can get it from the WeakMap
.
The difference between Map
and WeakMap
is that the latter does not hold reference to the key, if the garbage collector needs to clear it from the memory, WeakMap
will say that it is fine, the key and value will be cleared at the same time.
Caching
The power this characteristic gives us is that we can start caching things without the risk of causing a memory leak. If the key is ready to be collected, the cache won't be a problem in the way of GC.
We can implement a higher-order function called weakMemoize
that will decorate our function with a caching layer using a WeakMap
.
function weakMemoize(toDecorate) {
const cache = new WeakMap()
return function (value) {
if (!cache.has(value)) {
cache.set(value, toDecorate(value))
}
return cache.get(value)
}
}
Then we can use to cache our functions
const getKeys = weakMemoize((value) => {
return Object.keys(value)
})
const obj = { a: 10, b: 20, c: 30 }
getKeys(obj)
// second time the value is read from the cache.
getKeys(obj)
I'm not concerned about the memory consumption of this because whenever obj
or getKeys
go out of scope, the garbage collector will also collect the values in the map. I'm avoiding executing Object.keys
a second time with no extra complexity in the implementation of my function.
Considerations
Couple of things to take in consideration. A WeakMap
key can only be an object (object
or Array
), we cannot use a primitive value as key.
Another consideration is that if you have long living objects, caching things like this, might not be so beneficial, a lot of objects will be retained in memory, consider using a LRU cache.
Also, you don't need to implement your own weakMemoize
, there are good implementations in the npm.
Thanks for reading!
Saw a problem in my post? Please comment or reach me out on twitter.
Top comments (0)