JavaScript Storing temporary client side data

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.
Answer:1

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)

Answer:2

Using Javascript variable is the best way to store you temp data. You may consider to storing your data inside a DOM attribute only if the data is related to a specific DOM element.

About the performance, storing your data directly in a javascript variable will probably be faster since storing data in a DOM element would also involve javascript in addition to the DOM modifications. If the data isn't related to an existing DOM element, you'll also have to create a new element to store that value and make sure it isn't visible to the user.

Answer:3

The OP mentions a requirement for the data to be forcibly transient i.e. (if possible) unable to be saved locally on the client - at least that is how I read it.

If this type of data privacy is a firm requirement for an application, there are multiple considerations when dealing with a browser environment, I am unsure whether the images in question are to be displayed as images to the user, or where in relation to the client the source data of the images is coming from. If the data is coming into the browser over the network, you might do well (or better than the alternative, at least) to use a socket or other raw data connection rather than HTTP requests, and consider something like a "sentinel" value in the stream of bytes, to indicate boundaries of image data.

Once you have the bytes coming in, you could, I believe, (or soon will be able to) pass the data via a generator function into a typedArray via the iterator protocol, see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array

// From an iterable 
var iterable = function*(){ yield* [1,2,3]; }(); 
var uint8 = new Uint8Array(iterable); 
// Uint8Array[1, 2, 3]

And then perhaps integrate those arrays as private members of some class you use to manage their lifecycle? see:

https://www.nczonline.net/blog/2014/01/21/private-instance-members-with-weakmaps-in-javascript/

var Person = (function() {

    var privateData = {},
        privateId = 0;

    function Person(name) {
        Object.defineProperty(this, "_id", { value: privateId++ });

        privateData[this._id] = {
            name: name
        };
    }

    Person.prototype.getName = function() {
        return privateData[this._id].name;
    };

    return Person;
}());

I think you should be able to manage the size / wait problem to some extent with the generator method of creating the byte arrays as well, perhaps check for sane lengths, time passed on this iterator, etc.

A general set of ideas more than an answer, and none of which are my own authorship, but this seems to be appropriate to the question.

Answer:4

Is there any time when var result = !value ? null : value[0]; would not be equivalent to var result = value ? value[0] : null;

Is there any time when var result = !value ? null : value[0]; would not be equivalent to var result = value ? value[0] : null;

So I have a data.table object that is being outputed like this: gender hair-color pets group1.totals group2.totals group3.totals F black Y 10 0 ...

So I have a data.table object that is being outputed like this: gender hair-color pets group1.totals group2.totals group3.totals F black Y 10 0 ...

I am working on code written by someone else. To my knowledge its not correct but I am not seeing any errors and so now I am not sure if something changed since version 8. The code is as below & ...

I am working on code written by someone else. To my knowledge its not correct but I am not seeing any errors and so now I am not sure if something changed since version 8. The code is as below & ...

I am using AngularJS with MVC file structure. I have a data structure in my controller that I want to display on my view. I have a custom "indicators" directive. Each "title" belongs to an indicator ...

I am using AngularJS with MVC file structure. I have a data structure in my controller that I want to display on my view. I have a custom "indicators" directive. Each "title" belongs to an indicator ...