Knockout.js невероятно медленно работает с полубольшими наборами данных
Я только начинаю работать с Knockout.js (всегда хотел попробовать, но теперь у меня есть оправдание!) - Однако я сталкиваюсь с некоторыми очень плохими проблемами производительности при привязке таблицы к относительно небольшому набору данные (около 400 строк или около того).
В моей модели у меня есть следующий код:
this.projects = ko.observableArray( [] ); //Bind to empty array at startup
this.loadData = function (data) //Called when AJAX method returns
{
for(var i = 0; i < data.length; i++)
{
this.projects.push(new ResultRow(data[i])); //<-- Bottleneck!
}
};
Проблема заключается вfor
цикл выше занимает около 30 секунд или около того около 400 строк. Однако, если я изменю код на:
this.loadData = function (data)
{
var testArray = []; //<-- Plain ol' Javascript array
for(var i = 0; i < data.length; i++)
{
testArray.push(new ResultRow(data[i]));
}
};
Тогдаfor
цикл завершается в мгновение ока. Другими словами,push
метод нокаутаobservableArray
объект невероятно медленный
Вот мой шаблон:
<tbody data-bind="foreach: projects">
<tr>
<td data-bind="text: code"></td>
<td><a data-bind="projlink: key, text: projname"></td>
<td data-bind="text: request"></td>
<td data-bind="text: stage"></td>
<td data-bind="text: type"></td>
<td data-bind="text: launch"></td>
<td><a data-bind="mailto: ownerEmail, text: owner"></a></td>
</tr>
</tbody>
Мои вопросы:
Является ли это правильным способом связать мои данные (полученные из метода AJAX) с наблюдаемой коллекцией?я ожидаюpush
каждый раз, когда я его называю, выполняет некоторые сложные перерасчеты, например, возможно, перестраивает связанные объекты DOM. Есть ли способ отсрочить этот отзыв, или, может быть, сдвинуть все мои вещи сразу?Я могу добавить больше кода, если это необходимо, но я уверен, что это то, что важно. По большей части я просто следовал учебникам по нокауту с сайта.
ОБНОВИТЬ:
Следуя совету ниже, я обновил свой код:
this.loadData = function (data)
{
var mappedData = $.map(data, function (item) { return new ResultRow(item) });
this.projects(mappedData);
};
Тем не мение,this.projects()
все еще занимает около 10 секунд для 400 строк. Я признаю, я не уверен, насколько быстро это будетбез Нокаут (просто добавление строк через DOM), но я чувствую, что это будет намного быстрее, чем 10 секунд.
ОБНОВЛЕНИЕ 2:
По другим советам ниже я далjQuery.tmpl выстрел (который изначально поддерживается KnockOut), и этот шаблонный движок будет рисовать около 400 строк всего за 3 секунды. Это кажется лучшим подходом, если не считать решения, которое бы динамически загружало больше данных при прокрутке.