#c# #asp.net-mvc #slickgrid
#c# #asp.net-mvc #slickgrid
Вопрос:
итак, я использую MVC 4 C # / Razor и разрабатываю страницу, которая использует SlickGrid для отображения данных сетки. Все работает нормально, за исключением случаев, когда я пытаюсь использовать его для отображения большого объема данных (что-то вроде 1 миллиона строк).
Когда это происходит, кажется, что все работает нормально, пока не будет почти закончено. Как раз в тот момент, когда кажется, что это будет сделано со всей загрузкой данных, веб-страница выходит из строя. Я использую getJSON для извлечения данных из базы данных SQL. Я делаю это по столбцам и партиями по 300000 записей. Я пробовал использовать инструменты профилирования памяти Chrome и не смог найти ничего полезного. Ниже приведены некоторые фрагменты кода:
function pullAllGridData(tableName, colArray)
{
for (var i = 0; i < colArray.length; i )
{
fetchColumn(tableName, colArray[i], 0);
}
}
function fetchColumn(tableName, fieldName, startAt)
{
$.getJSON('/WIMenu/GetTableData', { tableName: tableName, fieldName: fieldName }, function (data)
{
if (data.slice(-1) !== '~')
{
var startPass = populateSlickData(data, fieldName, startAt);
colStatus[fieldName] = true;
if (loadFirstBatch())
{ populateGrid(); }
fetchColumn(tableName, fieldName, startPass);
}
else
{
data = data.slice(0, -1);
populateSlickData(data, fieldName, startAt);
colStatus[fieldName] = true;
if (loadFirstBatch())
{ populateGrid(); }
}
});
}
function populateSlickData(input, fieldName, startAt)
{
var output = startAt;
var valueArray = input.split('|');
output = valueArray.length;
if (!isInBlackList(fieldName, tableName))
{
var datatype = columns[getColumnIndex(fieldName)].datatype;
var startIndex = startAt;
var endIndex = startAt valueArray.length;
var counter = 0;
alert(fieldName ': startIndex: ' startIndex ' endIndex: ' endIndex ' count: ' endIndex-startIndex);
for (var x = startIndex; x < endIndex; x )
{
if (!slickdata[x])
{ slickdata[x] = {}; }
if (valueArray[x - startAt] == 'null') { valueArray[x - startAt] = ''; }
if (datatype == 'System.DateTime')
{
if (valueArray[x-startAt] !== '')
{
var date = new Date(valueArray[x - startAt]);
valueArray[x - startAt] = (date.getMonth() 1) '-' date.getDate() '-' date.getFullYear();
}
}
else if (datatype == 'System.Decimal' || datatype == 'System.Int32' || datatype == 'System.Int16' || datatype == 'System.Int64')
{
valueArray[x - startAt] = parseFloat(valueArray[x - startAt]);
}
slickdata[x][fieldName] = valueArray[x - startAt];
counter ;
}
}
currentColumn = fieldName;
filteredData = slickdata;
return output;
}
fetchColumn использует рекурсию для продолжения получения данных столбца, пока все они не будут получены. Метод populateGrid просто синхронизирует объект SlickGrid с объектом slickdata. Моя цель здесь — выяснить, почему происходит сбой страницы, и узнать, как это можно исправить.
При использовании оповещений кажется, что в какой-то момент он застревает в цикле for в методе populateSlickData, и я не могу понять, почему. Я пробовал печатать данные для индексации, но, похоже, все нормально.
Комментарии:
1. Действительно интересно, действительно ли рекурсия необходима? Не было бы более эффективным выполнить только один вызов ajax и вернуть все?
2. @gustavodidomenico — Я не вижу никакой рекурсии в примере… Действительно, обратный вызов снова вызывает функцию out, но я бы не назвал это рекурсией.
3. Примечание: В других профессиях это может называться нагрузочным тестом крыла … Действительно, любая часть программного / аппаратного обеспечения сломается, если вы приложите к ней достаточную нагрузку. Некоторые более устойчивы, но действительноли 1 миллион записей для показа в браузере?
4. Я думаю, что людям не хватает леса для деревьев. Он одновременно загружает В ПАМЯТЬ МИЛЛИОН строк данных.
5. Миллион строк из JSON в браузере. Сервер, конечно, может справиться с такой нагрузкой, но даже если браузер может хранить столько данных / много объектов, рендеринг не пройдет должным образом.
Ответ №1:
Вы не можете перенести миллион строк данных в память и ожидать, что любая веб-страница будет выполнять что-либо иное, кроме замедления обхода или даже сбоя. Для этого и предназначена подкачка по сетке в сочетании с ajax по требованию. Ваша сетка должна извлекать данные, необходимые для отображения текущей страницы данных, только при изменении страницы. Вы не должны загружать все заранее.
Вот пример на сайте SlickGrid github:http://mleibman.github.io/SlickGrid/examples/example4-model.html
Вот дополнительная информация:https://github.com/teleological/slickback/wiki/Pagination
Комментарии:
1. Хммм, я думал, что подкачка страниц была встроена в SlickGrid внутренне… Я думаю, что вы, возможно, указали мне правильный путь.
2. разбивка на страницы встроена в slickgrid, но вам нужна комбинация разбивки на страницы и загрузки по требованию. Если вы загрузили десять тысяч строк в память, разбиение на страницы возможно, но это все равно десять тысяч строк в памяти, когда вы показываете только пятьдесят одновременно. Вы хотите, чтобы сетка использовала ajax только при переключении страницы. Вы не должны загружать их все заранее 🙂
3. Итак, конечная цель здесь — создать сетку, которая позволит пользователям фильтровать данные в меньших объемах, которые они будут фактически наблюдать и использовать. Похоже, вы хотите сказать, что простой размер объекта slickdata приводит к сбою страницы (пожалуйста, поправьте меня, если я вас неправильно понимаю). Итак, еще раз поправьте меня, если я ошибаюсь, вы говорите, чтобы настроить мое взаимодействие с JSON / веб-сервером только для получения данных с сервера, когда пользователь фильтрует или прокручивает?
4. Я думаю, что собираюсь полностью реструктурировать все это, чтобы функционировать таким образом, чтобы браузер действительно мог справиться. Этот ответ является основой для моего пересмотра. Спасибо @x0n!
5. @peppajack да — именно огромный размер данных, которые вы загрузили в память, вызывает сбой браузера. Конечно, браузеры не должны аварийно завершать работу, но нехватка памяти — хороший способ сделать это.