我正在從一個數據庫中提取許多記錄並呈現給一個表的應用程序。這是通過AJAX調用完成的,並將它們追加到已經存在的結果的末尾。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
被鎖定瀏覽器並導致直到附加已經完成它是反應遲鈍。我已經分解了所以它會批量獲取數據,但這不是問題,它處理響應中的行。
問題:
有沒有辦法來處理批次的結果,並追加,如果沒有它鎖定了瀏覽器嗎?它自己的反應只是附加到我的表的TBODY
後面的一堆TR
。我最後的手段是不得不分頁。如果我能解決這個問題,我可以說服他們爲更大的數據集進行分頁。
我想我正在尋找一種方法來以更好的格式返回結果,以便追加或分解響應,並在批量追加時另一個AJAX調用正在獲取更多要處理的數據。
想法?
將大量行附加到表中將始終是殺手鐗。 – epascarello
窗口。requestAnimationFrame(fetchMore); –
作爲用戶滾動,您可以等待加載更多嗎? –