Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript : Fastest way to insert DOM element in sort order

so I've got several (~30) async calls returning with data (~25 records per call), which I want to display in a specific order.

Currently, the page waits for everything to load, sorts a single internal array, then adds the DOM elements (each item of data is applied to an HTML template/string which is effectively concatenated and added once to the parent element's innerHTML).

I'd LIKE the data to be inserted with each dataset (as it comes back)... but that implies that I need a different way to handle the sort/ordering.

Approaches I've considered:

  • Ideally, mirror the DOM in some sort of B-Tree, so that INSERT operations just traverse the tree looking for the correct element to insertBefore/insertAfter... since I've yet to see any library to address this need, it seems like I'd end up writing a bit of code.

  • manually iterate the DOM looking for the element to insertAfter... seems tediously slow, relatively speaking.

  • just use jQuery.sort(fn) after loading each dataset... seems hacky at best (given the number of times it'd be run, and the volume of DOM manipulation), but by far the easiest to implement code-wise, since it's like 5 lines.

  • I considered some sort of buffer queue between the async returns and the DOM manipulation, but there's far too much that I DON'T know about JS and threading to feel comfortable with that method.

I like the idea of inserting directly into the sorted slot, but I am aware that DOM manipulation can be "slow" (depending on how it's done, etc - and I am by no means a JS guru - thus asking here). The idea of the buffer queue with a separate reader/DOM handling seemed like it might provide a reasonable compromise between responsiveness and the DOM manipulation pains, but that's all theoretical for me at this point... and all said and done, if it ends up being more hassle than it's worth, I'll either leave as-is, or just go the lazy route of jQ.sort the DOM.

your knowledgeable advise would be greatly appreciated :)

Thanks

like image 252
Scott Brickey Avatar asked Jan 18 '17 15:01

Scott Brickey


1 Answers

I'd go with Option 2. The DOM is just objects in a tree structure, so there's no need for a separate abstract tree other than if you want one. You can associate data directly with the elements via attributes or expando properties (if doing the latter, beware of naming conflicts, pick something very specific to your project) — the latter have the advantage of speed and not being limited to strings.

Searching through a list of DOM elements isn't markedly slow at all, nor is it much work.

Example inserting random numbers in divs within a container div:

var container= document.getElementById("container");

function insertOne() {
  // Our random number
  var num = Math.floor(Math.random() * 1000);
  
  // Convenient access to child elements
  var children = Array.prototype.slice.call(container.children);
  
  // Find the one we should insert in front of
  var before = children.find(function(element) {
    return element.__x__random > num;
  });
  
  // Create the div
  var div = document.createElement('div');
  div.innerHTML = num;
  div.__x__random = num;
  
  // Insert (if `before` is null, it becomes an append)
  container.insertBefore(div, before);
}

// Do it every 250ms
var timer = setInterval(insertOne, 250);

// Stop after 5 seconds
setTimeout(function() {
  clearInterval(timer);
}, 5000);
<div id="container"></div>
like image 113
T.J. Crowder Avatar answered Nov 15 '22 00:11

T.J. Crowder