global variables in JS vs local storage vs values in DOM, which one will be more efficient?
Global variables
Global variables are stored in memory and are attached to the window object. If you're going to use a lot of variables then it's best that you create a namespace object to act as a container. One problem with using global variables is they can easily be overwritten if there is a name collision.
Here is a non-destructive creation of a simple myNamespace object:
var myNamespace = window.myNamespace || {};
myNamespace.variable = 'Some value';
Depending on your situation you might want to populate the namespace by generating JSON using the server side application and inserting it into the HTML within a script fragment.
Seeing as you tagged your question with PHP, I'll add a small example using PHP's json_encode:
<?php
$book = array(
"title" => "Eloquent JavaScript",
"author" => "Marijn Haverbeke",
"edition" => 2
);
?>
<script>
var myNamespace = '<?php echo json_encode($book, JSON_PRETTY_PRINT) ?>';
/* var myNamespace = {
"title": "Eloquent JavaScript",
"author": "Marijn Haverbeke",
"edition": 2
};
*/
</script>
The JSON_PRETTY_PRINT parameter is optional, it prints the JSON in a readable format by adding lots of whitespace which you may not want. Using this approach the code namespace object is populated once the JavaScript has been parsed by the browser.
An alternative approach would be to use a function to populate the namespace object. In the following code fragment myNamespace is assigned the value returned by the IIFE that receives the parameter namespace. The value of the parameter is either window.myNamespace or an empty object, depending on whether or not myNamespace has been previously declared. Within this function AJAX calls can be used to populate the properties of the namespace object.
var myNamespace = (function(namespace) {
namespace.a = (function() { return ... })();
namespace.b = (function() { return ... })();
return namespace;
})(window.myNamespace || {});
Using AJAX to populate the namespace will increase the number of network requests to load the content.
DOM values
DOM values are everything in the HTML code, including attributes.
<img src="path/to/image.jpg" id="myId" class="myClass" title="My title" data-owner="Joe Bloggs" data-year="2017" />
DOM elements have an attributes property which contains all of the attribute names and values. Retrieving the data will be slower than grabbing it directly from a global variable because each document.getElement...
call means traversing the DOM tree.
var attrs = document.getElementById('unique-id').attributes;
// returns NamedNodeMap {0: id, 1: class, 2: data-owner, 3: data-year, 4: title ...}
Array.prototype.slice.call
can convert the result to an array which you can iterate over:
Array.prototype.slice.call(document.getElementById('myId').attributes)
.forEach(function(item) {
console.log(item.name + ': '+ item.value);
});
// class: myClass
// data-owner: Joe Bloggs
// data-year: 2017
// id: myId
// src: path/to/image.jpg
// title: My title
LocalStorage
localStorage is persistent key/value storage with same-origin rules applied, to avoid problems you need to use the same protocol and domain to access shared localStorage. The different implementations of 'Private Browsing' in web browsers means that you cannot rely on the feature being available and working as expected.
The cross-storage package from Zendesk allows you to share localStorage across domains.
Performance
Global variables > DOM values > LocalStorage > AJAX
- Global variables are in memory.
- DOM values means walking the tree which can be slow.
- LocalStorage means reading/writing to disk.
- AJAX requests means you have additional network latency.
- Global variable -> Values can be accessed within the js or page
- Localstorage -> Values can be accessed throughout the application(all pages).
In order of efficiency:
- JS globals
- The DOM
- localStorage and sessionStorage
The DOM and Javascript globals are both stored in RAM/ system memory. Globals are essentially just raw storage with very little structure, making them very fast. The DOM is highly structured and whenever it changes it issues a range of events - these events (such as triggering style updates and mutation events/ mutation observers) add to the overhead.
They're both completely destroyed whenever the webpage is closed (or whenever the browser is closed, or the device is turned off).
localStorage however, is stored on the hard drive. It has all the overhead of writing out to the disk every time it's used, but it's persistent - if the browser is closed, or the device is turned off, the data you put in there will still be available. It's best used for e.g. caching files.
Most data in Javascript is completely temporary, so most of the time, you'd use globals.