我正在开发一个从数据库中获取许多记录并将其呈现到表中的应用程序。这是通过AJAX调用完成的,并将它们附加到已经存在的结果的末尾。

在这种情况下,记录数是变量,取决于搜索条件返回的内容,可以是10或20,000。

现在,首先是第一件事。我了解在页面上拥有20,000条记录并不明智,但这是允许从此页面上查看,修改或标记所有记录的要求。

对PHP页面的AJAX调用很好,并且似乎运行很快。但是,瓶颈是一旦通过AJAX接收到该数据,就会将该数据附加到DOM。

在下面的代码中,您将看到创建表行并将其返回给AJAX调用的主要功能。

/*
  Create Table Rows
*/
function createTableRows($dashboardID, $type){

  // Timer
  $start = microtime(true);

  // Dashboard
  $dashboardID = $_REQUEST['dashboardID'];
  $objDB = new DB;
  $objData = $objDB
    -> setStoredProc('RenderDashboard')
    -> setParam('dashboardID', $dashboardID)
    -> setParam('limit', $_REQUEST['limit'])
    -> setParam('offset', $_REQUEST['offset'])
    -> setParam('actor', '1234')
    -> execStoredProc()
    -> parseXML();

    // Fetch other data
    $markupData = fetchMarkup($dashboardID);
    $exportFields = fetchExportFields($dashboardID);
    $ignore = Array('identifierQID', 'identifierNTID');

    // Vars
    $outputArray = Array();
    $recordCount = 0;
    $i = 0;

    // Loop over our data
    foreach($objData->data as $r){

      $outputArray[$i++] = '<tr data-qid="'.$r->identifierQID.'" class="primaryValue ' . searchMarkup($markupData, $r->identifierQID) . '">';

        // Loop over our fields
        foreach($r as $key => $value){

          // Vars
          $fieldID = str_replace('_', '', $key);

          // Don't include our identifier columns
          if(!in_array($fieldID, $ignore)){
            $outputArray[$i++] = '<td data-tableexport-display="always" class="small' . ($exportFields ? (in_array($fieldID, $exportFields) ? ' hidden' : '') : '') . '">' . formatFieldData($fieldID, $value) . '</td>';
          }

        }

        // Notes always come last
        $outputArray[$i++] = '<td data-tableexport-display="always" class="notesTD allowContext hidden"></td>';

      $outputArray[$i++] = '</tr>';
      $recordCount++;

    }

    // Join our rows array and return it
    $end = microtime(true);
    $timer = number_format($end - $start, 2);
    return array(join("",$outputArray), $recordCount, $timer);
}

// This is what gets passed back to our AJAX call on the UI
echo createTableRows($dashboardID)[0];


这是处理收到的响应的Javascript。

// Given data, create our table rows
function createRows(data) {

    // Update Progress Bar
    $('[name=progressDiv]').show();

    // Append the results to the DOM
    /* THIS IS WHAT IS KILLING THE SPEED!!!!*/
    $('[name=resultsTable]').append(data);

    // If our total number of records exceeds the threshold, we will be using the progress bar for the status
    if (totalRecords > maxThreshold) {
        $('[name=resultsProgress]').attr('aria-valuenow', currentPage / totalPages * 100)
            .css('width', currentPage / totalPages * 100 + '%')
            .text((currentPage < totalPages ? recordsPerPage * currentPage + ' of ' + totalRecords + ' records loaded' : 'Loaded ' + totalRecords + ' records!'));
    } else {
        // Loaded all records in one shot, update progress bar
        $('[name=resultsProgress]').attr('aria-valuenow', 100)
            .css('width', '100%')
            .text('Loaded ' + totalRecords + ' records!')
            .removeClass('active');
    }
    // Do we have more data to load?
    if (currentPage < totalPages && totalRecords > maxThreshold) {
      // Allow a little time for the progress to update before locking up
      setTimeout(function(){
        fetchMore();
      }, 100);

    }

    // After the table has been appended to the DOM, run clean up to enable any additional functionality
    cleanUp();
}


问题:

问题在于APPEND锁定了浏览器,并导致它在添加完成之前无法响应。我已经对此进行了分解,因此它将分批获取数据,但这不是问题,它可以处理响应中的行。

问题:

有没有一种方法可以批量处理结果并追加结果,而不会锁定浏览器?它本身的响应只是一堆TR附加到表的TBODY中。

我的最后一招是必须分页结果。如果可以解决这个瓶颈,我可以说服他们对较大的数据集进行分页。

我想我正在寻找一种方法,可以以更好的格式返回结果以追加或分解响应,并分批追加,而另一个AJAX调用正在提取更多数据进行处理。

有什么想法吗?

最佳答案

您可以使用Javascript表组件来处理大量JSON数据的显示。例如:https://clusterize.js.org/

10-05 20:31
查看更多