Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing temporary client side data

Tags:

javascript

I need to store client side data temporarily. The data will be trashed on refresh or redirect. What is the best way to store the data?

using javascript by putting the data inside a variable

var data = {
    a:"longstring",
    b:"longstring",
    c:"longstring",
}

or

putting the data inside html elements (as data-attribute inside div tags)

<ul>
    <li data-duri="longstring"></li>
    <li data-duri="longstring"></li>
    <li data-duri="longstring"></li>
</ul>

The amount of data to temporarily store could get a lot because the data I need to store are image dataUri's and a user that does not refresh for the whole day could stack up maybe 500+ images with a size of 50kb-3mb. (I am unsure if that much data could crash the app because of too much memory consumption. . please correct me if I am wrong.)

What do you guys suggest is the most efficient way to keep the data?

like image 241
Jo E. Avatar asked Mar 18 '23 10:03

Jo E.


2 Answers

I'd recommend storing in JavaScript and only updating the DOM when you actually want to display the image assuming all the image are not stored at the same time. Also note the browser will also store the image in its own memory when it is in the DOM.

Update: As comments have been added to the OP I believe you need to go back to customer requirements and design - caching 500 x 3MB images is unworkable - consider thumbnails etc? This answer only focuses on optimal client side caching if you really need to go that way...

Data URI efficiency

Data URIs use base64 which adds an overhead of around 33% representing binary data in ASCII.

Although base64 is required to update the DOM the overhead can be avoided by storing the data as binary strings and encoding and decoding using atob() and btoa() functions - as long as you drop references to the original data allowing it to be garbage collected.

var dataAsBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";

var dataAsBinary = atob(dataAsBase64);
console.log(dataAsBinary.length + " vs " + dataAsBase64.length);

// use it later
$('.foo').attr("src", "data:image/png;base64," + btoa(dataAsBinary));

String memory efficiency

How much RAM does each character in ECMAScript/JavaScript string consume? suggests they take 2 bytes per character - although this is still could be browser dependent.

This could be avoided by using ArrayBuffer for 1-to-1 byte storage.

var arrayBuffer = new Uint8Array(dataAsBinary.length );
for (i = 0; i < dataAsBinary.length; i++) {
    arrayBuffer[i] = dataAsBinary.charCodeAt(i);
}
// allow garbage collection
dataAsBase64 = undefined;

// use it later
dataAsBase64 = btoa(String.fromCharCode.apply(null, arrayBuffer));
$('.foo').attr("src", "data:image/png;base64," + btoa(dataAsBinary));

Disclaimer: Note all this add a lot of complexity and I'd only recommend such optimisation if you actually find a performance problem.

Alternative storage

Instead of using browser memory

  • local storage - limited, typically 10MB, certainly won't allow - 500 x 3MB without specific browser configuration.
  • Filesystem API - not yet widely supported, but ideal solution - can create temp files to offload to disk.
like image 130
Adam Avatar answered Mar 23 '23 00:03

Adam


if you really want to loose the data on a refresh, just use a javascript hash/object var storage={} and you have a key->value store. If you would like to keep the data during the duration of the user visiting the page (until he closes the browser window), you could use sessionStorage or to persist the data undefinetly (or until the user deletes it), use localStorage or webSQL

putting data into the DOM (as a data-attribute or hidden fields etc) is not a good idea as the process for javascript to go into the DOM and pull that information out is very expensive (crossing borders between the javascript- and the DOM-world (the website structure) doesn't come cheap)

like image 43
japrescott Avatar answered Mar 22 '23 23:03

japrescott