title: Dynamically Created Html table rendering slow for huge records
body: <p>This is how I am creating my table &amp; rendering into the aspx page after getting the data from from database by ajax call. I checked the stored procedure execution Time which is only 1.5 seconds where table in my page renders about in 7- 8 seconds. I need to optimize the speed. Any suggestion how I can  do it?</p>
  
  <pre><code>$.ajax({
      method: 'POST',
      //async: false,
      data: json_data,
      dataType: 'json',
      url: json_url
  }).success(function (response) {
      if (response.IsError) {
          showError('Did not receive values from XRM.');
      } else {
          var webResponse = response;
          var dataSet = webResponse["Orders"];
          var statuses = [];
  
          //console.log(dataSet);
  
          if (table_role == 'pending') {
              statuses = [
                  {
                      'id': 39,
                      'name': 'Pending Scheduling',
                      'class': 'schedule',
                      'color': '#7C44BC',
                      'order': 0
                  },
                  {
                      'id': 40,
                      'name': 'Pending Screening',
                      'class': 'screening',
                      'color': '#8e8e00',
                      'order': 1
                  },
                  {
                      'id': 41,
                      'name': 'Pending Pre-Auth',
                      'class': 'preauth',
                      'color': '#cc8500',
                      'order': 2
                  },
                  {
                      'id': 42,
                      'name': 'Ready For Confirmation',
                      'class': 'confirm',
                      'color': '#cc0070',
                      'order': 3
                  },
                  {
                      'id': 1,
                      'name': 'Open',
                      'class': 'open',
                      'color': null,
                      'order': 4
                  },
                  {
                      'id': 2,
                      'name': 'New Order',
                      'class': 'neworder',
                      'color': null,
                      'order': 5
                  },
                  {
                      'id': 3,
                      'name': 'Changed',
                      'class': 'changed',
                      'color': '#cd4e3e',
                      'order': 6
                  },
                  {
                      'id': 5,
                      'name': 'Approved',
                      'class': 'approved',
                      'color': '#6aa745',
                      'order': 7
                  },
                  {
                      'id': 6,
                      'name': 'On Hold',
                      'class': 'onhold',
                      'color': '#009acd',
                      'order': 8
                  },
                  {
                      'id': 11,
                      'name': 'In Queue',
                      'class': 'queue',
                      'color': null,
                      'order': 9
                  }
              ];
  
              // For customers, change labels
              if (is_customer) {
                  statuses[5]['name'] = 'Submitted to SMS';
                  statuses[9]['name'] = 'Approved';
              }
          } else if (table_role == 'preauth') {
              statuses = [
                  {
                      'id': 29,
                      'name': 'More Info Needed',
                      'class': 'moreinfo',
                      'order': 0
                  },
                  {
                      'id': 43,
                      'name': 'Phone Order',
                      'class': 'phone',
                      'order': 1
                  },
                  {
                      'id': 30,
                      'name': 'Received Order',
                      'class': 'received',
                      'order': 2
                  },
                  {
                      'id': 31,
                      'name': 'Waiting on Documentation',
                      'class': 'waiting',
                      'order': 3
                  },
                  {
                      'id': 32,
                      'name': 'Courtesy Call Pending',
                      'class': 'courtesy-pending',
                      'order': 4
                  },
                  {
                      'id': 33,
                      'name': 'Courtesy Call Complete',
                      'class': 'courtesy-complete',
                      'order': 5
                  },
                  {
                      'id': 34,
                      'name': 'In Pre-Authorization',
                      'class': 'preauth',
                      'order': 6
                  },
                  {
                      'id': 35,
                      'name': 'Additional Docs Needed',
                      'class': 'addtldocs',
                      'order': 7
                  },
                  {
                      'id': 36,
                      'name': 'Pending Authorization',
                      'class': 'pending',
                      'order': 8
                  }
              ];
          }
  
          // Remove any "sorting" backgrounds from headers
          $th.removeClass('otable__sort');
  
          // If no orders available
          if ($.isEmptyObject(dataSet)) {
              $table.find('.otable__empty').css('display', 'table-cell');
          } else {
              // Loop through orders
              $.each(dataSet, function (key, value) {
                  if (table_role == 'pending') {
                      var id = (value['ID'] == null) ? '' : value['ID'],
                          date = (value['ID'] == null) ? '' : value['ExamDate'],
                          billing = (value['BillCode'] == null) ? '' : value['BillCode'],
                          scanner = (value['ScannerCode'] == null) ? '' : value['ScannerCode'],
                          units = (value['Unit'] == null) ? '' : value['Unit'],
                          by = (value['EmployeeName'] == null) ? '' : value['EmployeeName'],
                          status = value['StatusID'],
                          customer = value['Customer'],
                          location = '';
  
                      // Build location string
                      if (value['Facility']) {
                          location += value['Facility'] + '&lt;br&gt;';
                      }
                      if (value['City'] &amp;&amp; value['State']) {
                          location += value['City'] + ', ' + value['State'];
                      }
                  } else if (table_role == 'preauth') {
                      var id = (value['ID'] == null) ? '' : value['ID'],
                          poid = (value['POID'] == null) ? '' : value['POID'],
                          site = (value['Site'] == null) ? '' : value['Site'],
                          patient = (value['PatientName'] == null) ? '' : value['PatientName'],
                          insurance_co = (value['InsuranceCo'] == null) ? '' : value['InsuranceCo'],
                          received_date = (value['ReceivedDate'] == null) ? '' : value['ReceivedDate'],
                          exam_date = (value['ExamDate'] == null) ? '' : value['ExamDate'],
                          updated_date = (value['UpdatedDate'] == null) ? '' : value['UpdatedDate'],
                          status = value['StatusID'],
                          priority = (value['Priority'] == null) ? 0 : value['Priority'],
                          custid = (value['custID'] == null) ? '' : value['custID'];
                  }
  
                  // Find status from ID
                  var object = $.grep(statuses, function (element, index) {
                      return element['id'] == status;
                  });
                  object = object[0];
  
                  // Get status name
                  var status_name = object['name'],
                      status_pos = object['order'],
                      status_class = object['class'],
                      datestring = '',
                      received_datestring = '',
                      exam_datestring = '',
                      updated_datestring = '';
  
                  // Build date strings
                  if (date) {
                      datestring = splitDate(date);
                  }
                  if (received_date) {
                      received_datestring = splitDate(received_date);
                  }
                  if (exam_date) {
                      exam_datestring = splitDate(exam_date);
                  }
                  if (updated_date) {
                      updated_datestring = splitDate(updated_date);
                  }
  
                  // Build Time strings
                  if (updated_date) {
                      updated_timestring = splitTime(updated_date);
                  }
                  else {
                      updated_timestring = '';
                  }
  
                  // Convert priority for sorting
                  var priority_order;
                  if (priority) {
                      if (priority == 0) {
                          priority_order = 2;
                      } else if (priority == 5) {
                          priority_order = 1;
                      } else if (priority == 10) {
                          priority_order = 0;
                      }
                  }
  
                  // HTML for table row
                  var $row;
  
                  if (table_role == 'pending') {
                      if (!is_customer &amp;&amp; (is_scheduler || is_retail)) {
                          $row = $('&lt;tr class="otable__row otable__row--' + status_class + '"&gt;' +
                                    '&lt;td class="otable__id"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + id + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__date" data-sort-value="' + date + '"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + datestring + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__billing"&gt;&lt;a href=#rptPendingGroupByOrder onclick=showDialog(\'/CustomerProfile.aspx?cid=' + customer + '\')&gt;' + billing + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__scanner"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + scanner + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__loc"&gt;&lt;a href=#rptPendingGroupByOrder onclick=showDialog(\'/CustomerProfile.aspx?cid=' + customer + '\')&gt;' + location + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__units"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + units + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__by"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + by + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__status" data-status-id="' + status + '" data-sort-value="' + status_pos + ' ' + date + '"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + status_name + '&lt;/a&gt;&lt;/td&gt;' +
                                  '&lt;/tr&gt;');
                      } else if (!is_customer &amp;&amp; (!is_scheduler || !is_retail)) {
                          $row = $('&lt;tr class="otable__row otable__row--"&gt;' +
                                    '&lt;td class="otable__id"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + id + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__date" data-sort-value="' + date + '"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + datestring + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__billing"&gt;&lt;a href=#rptPendingGroupByOrder onclick=showDialog(\'/CustomerProfile.aspx?cid=' + customer + '\')&gt;' + billing + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__scanner"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + scanner + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__loc"&gt;&lt;a href=#rptPendingGroupByOrder onclick=showDialog(\'/CustomerProfile.aspx?cid=' + customer + '\')&gt;' + location + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__units"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + units + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__by"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + by + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__status" data-status-id="' + status + '" data-sort-value="' + status_pos + ' ' + date + '"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + status_name + '&lt;/a&gt;&lt;/td&gt;' +
                                  '&lt;/tr&gt;');
                      } else {
                          $row = $('&lt;tr class="otable__row otable__row--customer otable__row--' + status_class + '"&gt;' +
                                    '&lt;td class="otable__id"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + id + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__date" data-sort-value="' + date + '"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + datestring + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__units"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + units + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__by"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + by + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__status" data-status-id="' + status + '" data-sort-value="' + status_pos + ' ' + date + '"&gt;&lt;a href=/Customer/FDGOrders.aspx?oid=' + id + '&gt;' + status_name + '&lt;/a&gt;&lt;/td&gt;' +
                                  '&lt;/tr&gt;');
                      }
                  } else if (table_role == 'preauth') {
                      var insurance_sort_val = priority_order;
                      if (exam_date &amp;&amp; exam_date.indexOf('0001-01-01') &lt; 0) {
                          insurance_sort_val = priority_order + ' ' + exam_date;
                      } else if (received_date) {
                          // Force items with null exam date to bottom, then sort by received date
                          insurance_sort_val = priority_order + ' Z ' + received_date;
                      }
  
                      $row = $('&lt;tr class="otable__row otable__row--' + status_class + '"&gt;' +
                                    '&lt;td class="otable__id"&gt;&lt;a href=""&gt;' + id + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__site"&gt;&lt;a href="/Customer/FDGOrders.aspx?oid=' + id + '"&gt;' + site + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__by"&gt;&lt;a href=""&gt;' + patient + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__insurance otable__priority--' + priority + '" data-sort-value="' + insurance_sort_val + '"&gt;&lt;a href=""&gt;' + insurance_co + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__date" data-sort-value="' + received_date + '"&gt;&lt;a href=""&gt;' + received_datestring + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__date" data-sort-value="' + exam_date + '"&gt;&lt;a href=""&gt;' + exam_datestring + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__status" data-status-id="' + status + '" data-sort-value="' + status_pos + ' ' + exam_date + '"&gt;&lt;a href=""&gt;' + status_name + '&lt;/a&gt;&lt;/td&gt;' +
                                    '&lt;td class="otable__date--wide" data-sort-value="' + updated_date + '"&gt;&lt;a href=""&gt;' + updated_datestring + ' ' + updated_timestring + '&lt;/a&gt;&lt;/td&gt;' +
                                  '&lt;/tr&gt;');
  
                      $row.find('a').on('click', function (e) {
                          if (!$(this).parent('.otable__site').length) {
                              e.preventDefault();
  
                              showDialog('/Customer/FDGPatientOrder.aspx?oid=' + id + '&amp;poid=' + poid);
                          }
                          if ($(this).parent('.otable__site').length) {
                              e.preventDefault();
  
                              showDialog('/CustomerProfile.aspx?cid=' + custid);
                          }
                      });
                  }
  
                  // Append to table body
                  $table.find('tbody').append($row);
              });
          }
  
          // Fire event
          //$table.trigger('all-rows-added');
          //$table.off('all-rows-added');
  
          // Table sorting functionality
          if (table_role == 'pending') {
              initTableSorting($table, 7);
          } else if (table_role == 'preauth') {
              initTableSorting($table, 3);
          }
  
          // Status filter functionality
          var $list = $table.find('.otable__status__list');
          // Clear previous filters
          $list.find('ul&gt;li:not(:first)').remove();
  
          // Loop through statuses to see which are contained in the table
          $.each(statuses, function (key, value) {
              if ($table.find('tbody').has('.otable__status[data-status-id="' + value.id + '"]').length &gt; 0) {
                  var $li;
  
                  if (table_role == 'pending') {
                      $li = $('&lt;li&gt;' +
                                '&lt;button data-filter="' + value.id + '" data-color="' + value.color + '"&gt;' +
                                  '&lt;div class="otable__legend"&gt;&lt;/div&gt;' +
                                  value.name +
                                '&lt;/button&gt;' +
                              '&lt;/li&gt;');
                  } else {
                      $li = $('&lt;li&gt;' +
                                '&lt;button data-filter="' + value.id + '"&gt;' +
                                  '&lt;div class="otable__legend"&gt;&lt;/div&gt;' +
                                  value.name +
                                '&lt;/button&gt;' +
                              '&lt;/li&gt;');
                  }
  
                  // Add the list item
                  $li = $li.appendTo($list.find('ul'));
  
                  // Set the legend color
                  var $btn = $li.find('button'),
                      filter = $btn.data('filter'),
                      color = $btn.data('color');
  
                  if (color !== null) {
                      $li.find('.otable__legend').css('background', color);
                  }
              }
          });
  
          $th.on('click', function (e) {
              // Check if main filter is being clicked, otherwise don't sort
              if ($list.has(e.target).length &gt; 0) {
                  var $target = $(e.target).closest('button'),
                      filter = $target.data('filter');
  
                  // Sort all rows by ascending status
                  $table.find('th').eq(7).stupidsort('asc');
  
                  // Style actively selected item
                  $list.find('li').removeClass('otable__status__checked');
                  $target.parent('li').addClass('otable__status__checked');
  
                  if (filter == 'all') {
                      $table.find('tbody &gt; tr').css('display', 'table-row');
                  } else {
                      $table.find('tbody &gt; tr').css('display', 'none');
                      $table.find('tbody &gt; tr').has('.otable__status[data-status-id="' + filter + '"]').css('display', 'table-row');
                  }
  
                  // Force hide list when option clicked
                  $list.css({
                      'clip': 'rect(0 0 0 0)',
                      'opacity': 0
                  });
                  // Restore default behavior once mouse is moved
                  $table.mousemove(function () {
                      $list.removeAttr('style');
                  });
  
                  // Prevent main sorting action
                  return false;
              }
          });
  
          // Sticky table header
          $table.stickyTableHeaders();
  
          // Remove loading indicator
          $table.find('.otable__loading').css('display', 'none');
      }
  }).fail(function (jqxhr, textStatus, error) {
      var err = textStatus + ", " + error;
      console.log("Failed to get XRM initialization values. Message: " + err);
  });
  </code></pre>