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 секунды. Это кажется лучшим подходом, если не считать решения, которое бы динамически загружало больше данных при прокрутке.

Ответы на вопрос(12)

Ваш ответ на вопрос