title: jQuery Very Slow during Loop, what can I improve?
body: <p>I have some code that is loading about 5,000 rows of data from a database. Once the AJAX call fetches the rows, it passes them to my function to create the rows. This function loops over the JSON data, creates our TR's, does some lookup's and then finally appends the full concatenated output to the DOM. </p>
  
  <p>On document load, I fetch 1,000 records and append it to the DOM for the user so they can see some of the data. I then have an AJAX call behind the scenes get the rest of it and append it when its done. The browser is locking up during this time though when it is looping over the data.</p>
  
  <p>During my testing, I commented out the <code>each loop</code> and the issue went away so I have narrowed it down to that. I am just not sure how I can improve this or if its the lookup function for <code>getObjects</code> that is delaying it.</p>
  
  <p>In the code sample below, the slowness begins at <code>$(data['data']['results']['data']).each(function() {</code>, at least, that's the block of code I commented out and it ran smoothly.</p>
  
  <p>Without leaving the question too open for resolution, what other options can i take aside from the <code>$.each</code> loop that may improve this or is it something happening within the loop that could be causing the slowness?</p>
  
  <pre><code>// Given data, create our table rows
  function createRows(data) {
  
      // Define our vars
      var output = '',
          markup = '';
  
      // Add the fields we chose to export to the array
      // We will then check this array when printing the columns to see if it should be shown or not
      if (isset(data.data.exportFields)) {
          $(data.data.exportFields.export).each(function() {
              exportFields.push(this.fieldID);
          });
      }
  
      // Loop over the core data
      $(data['data']['results']['data']).each(function() {
  
          // First level of data in our XML output
          core = $(this)[0];
  
          // Loop over our fields
          $(core['fields']['data']).each(function() {
  
              // Set a var for the field level data
              field = $(this)[0];
  
              // Do we have markup?
              if (isset(data.data.markup)) {
                  markup = '';
                  if (typeof getObjects(data.data.markup.data, 'QID', core.QID)[0] !== 'undefined') {
                      markup = getObjects(data.data.markup.data, 'QID', core.QID)[0].markup;
                  }
              }
  
              output += '&lt;tr class="primaryValue ' + markup + '" data-qid="' + core.QID + '"&gt;';
  
              // Loop over all the other rows 2 through x
              $.each(field, function(key, value) {
  
                  // Field Name Lookup
                  key = key.replace(/_/gi, '');
                  FieldNameLookup = getObjects(cfgFields.data.fields.options, 'FieldID', key)[0];
                  x = FieldNameLookup.FieldName;
                  val = (value.length ? value : '-')
  
                  // Is this an email address?
                  if (x.match(/email/gi)) {
                      output += '&lt;td data-tableexport-display="always" class="small ' + (jQuery.inArray(key, exportFields) != -1 ? 'hidden' : '') + '"&gt;';
                      output += '&lt;a href="mailto:' + val + '" class=""&gt;' + val + '&lt;/a&gt;';
                      output += '&lt;/td&gt;';
                  } else if (x.match(/NTID/gi)) {
                      output += '&lt;td data-tableexport-display="always" class="small ' + (jQuery.inArray(key, exportFields) != -1 ? 'hidden' : '') + '"&gt;';
                      output += '&lt;a href="https://website.com/profile/' + val + '" target="_BLANK" class=""&gt;' + val + '&lt;/a&gt;';
                      output += '&lt;/td&gt;';
                  } else {
                      output += '&lt;td data-tableexport-display="always" class="small ' + (jQuery.inArray(key, exportFields) != -1 ? 'hidden' : '') + ' allowContext"&gt;';
                      output += val;
                      output += '&lt;/td&gt;';
                  }
  
              });
  
              // End our row
              output += '&lt;td data-tableexport-display="always" class="notesTD allowContext hidden"&gt;&lt;/td&gt;';
              output += '&lt;/tr&gt;'
  
          });
      });
  
      // Append the results to the DOM
      $('[name=resultsTable]').append(output);
  
  }
  
  function getObjects(obj, key, val) {
      var objects = [];
      for (var i in obj) {
          if (!obj.hasOwnProperty(i)) continue;
          if (typeof obj[i] == 'object') {
              objects = objects.concat(getObjects(obj[i], key, val));
          } else if (i == key &amp;&amp; obj[key] == val) {
              objects.push(obj);
          }
      }
      return objects;
  }
  </code></pre>