Saya baru saja memulai dengan Knockout.js (selalu ingin mencobanya, tetapi sekarang saya akhirnya punya alasan!) - Namun, saya mengalami beberapa masalah kinerja yang sangat buruk saat mengikat tabel ke kumpulan yang relatif kecil. data (sekitar 400 baris atau lebih).
Dalam model saya, saya memiliki kode berikut:
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!
}
};
Masalahnya adalah for
loop di atas membutuhkan waktu sekitar 30 detik atau lebih dengan sekitar 400 baris. Namun, jika saya mengubah kodenya menjadi:
this.loadData = function (data)
{
var testArray = []; //<-- Plain ol' Javascript array
for(var i = 0; i < data.length; i++)
{
testArray.push(new ResultRow(data[i]));
}
};
Kemudian for
loop selesai dalam sekejap mata. Dengan kata lain, push
metode objek Knockout observableArray
sangat lambat.
Ini template saya:
<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>
Pertanyaan saya:
- Apakah ini cara yang tepat untuk mengikat data saya (yang berasal dari metode AJAX) ke koleksi yang dapat diamati?
- Saya berharap
push
melakukan beberapa penghitungan ulang berat setiap kali saya menyebutnya, seperti mungkin membangun kembali objek DOM yang terikat. Adakah cara untuk menunda penarikan kembali ini, atau mungkin memasukkan semua item saya sekaligus?
Saya dapat menambahkan lebih banyak kode jika diperlukan, tetapi saya cukup yakin inilah yang relevan. Untuk sebagian besar saya hanya mengikuti tutorial Knockout dari situs.
MEMPERBARUI:
Sesuai saran di bawah ini, saya telah memperbarui kode saya:
this.loadData = function (data)
{
var mappedData = $.map(data, function (item) { return new ResultRow(item) });
this.projects(mappedData);
};
Namun, this.projects()
masih membutuhkan waktu sekitar 10 detik untuk 400 baris. Saya akui, saya tidak yakin seberapa cepat ini tanpa Knockout (hanya menambahkan baris melalui DOM), tetapi saya merasa itu akan jauh lebih cepat dari 10 detik.
UPDATE 2:
Berdasarkan saran lain di bawah ini, saya memberi jQuery.tmpl kesempatan (yang secara native didukung oleh KnockOut), dan mesin templating ini akan menarik sekitar 400 baris hanya dalam waktu 3 detik. Ini sepertinya pendekatan terbaik, singkat dari solusi yang akan secara dinamis memuat lebih banyak data saat Anda menggulir.