70267

Storing elements in memory to prevent updating the DOM too often?

Question:

Currently I have a loop that updates the DOM in each iteration; I have learned this is a bad practice & you should update the DOM as little as possible for better speed.

So I was wondering how I go about editing the below so I can store all the elements in one element or something & then do a single DOM addition once the loop ends.

Here is the loop..

for (var i = spot; i < spot + batchSize && i < cats.options.length; i++) { // Check if the cat is selected if (cats.options[i].selected == true) { // Set this category's values to some variables var cat_id = cats.options[i].getAttribute('value'); var cat_name = cats.options[i].text; if (checkCatSICAdd(cat_id) === false) { // Now we create the new element var new_option = document.createElement('option'); // Add attribute new_option.setAttribute('value',cat_id); // Create text node var new_text_node = document.createTextNode(cat_name); // Append new text node to new option element we created new_option.appendChild(new_text_node); // Append new option tag to select list sel_cats.appendChild(new_option); } else { failed++; } } }

Answer1:

Working with DOM element in the loop is slow - no matter if you attach them to the document or not. Attaching them at the end is a bit faster since only only redraw is required but it's still slow.

The proper way is generating a plain old string containing HTML and attaching this string to the DOM using the innerHTML property of a DOM element.

Answer2:

Your code should be ok. The DOM won't actually redraw until the Javascript has finished executing. However, if you've encountered a problem browser that does perform badly, you could try creating a new select before your loop that is not yet attached to the DOM, populating it as you are now, then replacing sel_cats with that new select at the end. That way, the DOM is only updated once.

Answer3:

Your way is good enough unless you have great many items added to sel_cats - you add to the DOM only once.

The only way to improve efficiency might be to store the options as raw HTML then assign that after the loop:

var arrHTML = []; for (var i = spot; i < spot + batchSize && i < cats.options.length; i++) { // Check if the cat is selected if (cats.options[i].selected == true) { // Set this category's values to some variables var cat_id = cats.options[i].value; var cat_name = cats.options[i].text; if (checkCatSICAdd(cat_id) === false) { arrHTML.push("<option value=\"" + cat_id + "\">" + cat_name + "</option>"; } else { failed++; } } } sel_cats.innerHTML = arrHTML.join("");

Answer4:

Once you have the select list assigned to a variable, remove it from the dom using removeChild on its parent tag. You can then use appendChild in the loop before adding the select list back into the dom.

Answer5:

You might have a look at <a href="https://stackoverflow.com/questions/5536596/dynamically-creating-html-elemets-using-js/5536800#5536800" rel="nofollow">this</a> from earlier today.

not sure wether it will help but the topic is close enough :-) It's a discussion about adding elements to the DOM in-memory using documentFragment or in-memory elements.

Answer6:

Your code is way bloated, DOM 0 methods will be much faster.

If speed <em>really</em> matters, store spot + batchSize && i < cats.options.length in variables so they aren't re-calcuated on each loop (modern browsers probably don't, but older ones did):

for (var i=spot, j=spot+batchSize, k=cats.options.length; i < j && i < k; i++) { // Store reference to element var opt = cats.options[i]; // The selected property is boolean, no need to compare if (opt.selected) { // if checkCatSICAdd() returns boolean, just use it // but maybe you need the boolean comparison if (checkCatSICAdd(opt.name) === false) { // Wrapped for posting sel_cats.options[sel_cats.options.length] = new Option(opt.value, opt.name); } else { failed++; } } }

Recommend

  • Creating a layer of gradient within an SVG path dynamically
  • react native create element with string
  • Why does the following throw an “Object doesn't support property or method 'importNode
  • Getting error 'Cannot read property 'document' of undefined' while importing exp
  • Simple linked list-C
  • CakePHP ACL tutorial initDB function warnings
  • Automatically associate new Sonar project with custom quality profile and quality gate
  • why xml file does not aligned properly after append the string in beginning and end of the file usin
  • How do I access an unhandled exception in an MVC Error view?
  • How can I sort a a table with VBA with given text condition?
  • How to Cache Real-time Data?
  • Abort upload large uploads after reading headers
  • JSON response opens as a file, but I can't access it with JavaScript
  • Play WS (2.2.1): post/put large request
  • Set the selected item in dropdownlist in MVC3
  • Google Custom Search with transparent background
  • Python CGI os.system causing malformed header
  • FileReader+canvas image loading problem
  • DomPDF {PAGE_NUM} not on first page
  • How to make a tree having multiple type of nodes and each node can have multiple child nodes in java
  • HTML download movie download link
  • AES padding and writing the ciphertext to a disk file
  • How to convert from System.Drawing.Color to Excel.ColorFormat in C#? Change comment color
  • Why doesn't :active or :focus work on text links in webkit? (safari & chrome)
  • Validaiting emails with Net.Mail MailAddress
  • MySQL WHERE-condition in procedure ignored
  • vba code to select only visible cells in specific column except heading
  • Change an a tag attribute in JavaScript based on screen width
  • Web-crawler for facebook in python
  • trying to dynamically update Highchart column chart but series undefined
  • NSLayoutConstraint that would pin a view to the bottom edge of a superview
  • Hits per day in Google Big Query
  • Angular 2 constructor injection vs direct access
  • how does django model after text[] in postgresql [duplicate]
  • Java static initializers and reflection
  • Android Google Maps API OnLocationChanged only called once
  • How can i traverse a binary tree from right to left in java?
  • UserPrincipal.Current returns apppool on IIS
  • To Get the radio button value in ruby on rails
  • java string with new operator and a literal