Imagine we have a collection of objects with same schema (keys), but various
values. If we try to store this collection in the browser's localStorage
we quickly hit the
size limit (around 5MB). We can see the total size of each key in the localStorage
using local-storage-size.js browser console snippet in my code snippets repo.
But which key in the collection takes up more space than others? For example, in this collection,
key bar
is more expensive to store than foo
.
1 | var items = [ |
We can take JSON length as the object's size in memory. Since JavaScript uses UTF-16 each character could
take up to 2 bytes, thus I will take JSON.stringify(obj).length * 2
as the byte size of any object.
This gives us the first function
1 | function stringSize(str) { |
We can find out how expensive individual keys are by going through the collection, picking just the value for each key and measuring it. We also add the length of the key itself for each item. The code to extract values for each key and measure total space taken up the key and its value in the collection is:
1 | var value = function value(key) { |
I use small composable functions in my code because I like functional programming for its simplicity and testability. Finally, we can measure space for each key and zip the result object
1 | function zip(keys, values) { |
You can find the full script expensive-keys.js in the code snippets repo. It has a few extra features, like figuring out list of keys from first object, if no list is provided, and printing sizes in megabytes.
Update: keys-vs-values
I added another script keys-vs-values.js to the code snippets repo.
It measures space taken by keys vs space taken by values.
For example, object o
has keys that are much longer than the values it holds
1 | var o = { foo: 'f', bar: 'b' }; |
So in a list with single object o
keys take up 12 bytes, while values only take up 4 bytes.