이제 막 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
위 의 루프가 약 400 행으로 약 30 초 정도 걸린다는 것입니다. 그러나 코드를 다음과 같이 변경하면
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
Knockout의 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 개체를 다시 빌드하는 것과 같이 호출 할 때마다 무거운 재 계산을 수행 할 것으로 예상 합니다. 이 재 계산을 지연하거나 한 번에 모든 항목을 푸시 할 수있는 방법이 있습니까?
필요한 경우 더 많은 코드를 추가 할 수 있지만 이것이 관련성이 있다고 확신합니다. 대부분의 경우 사이트에서 Knockout 자습서를 따랐습니다.
최신 정보:
아래 조언에 따라 코드를 업데이트했습니다.
this.loadData = function (data)
{
var mappedData = $.map(data, function (item) { return new ResultRow(item) });
this.projects(mappedData);
};
그러나 this.projects()
여전히 400 행의 경우 약 10 초가 걸립니다. Knockout (DOM을 통해 행 추가) 없이 이것이 얼마나 빠를 지 잘 모르겠지만 10 초보다 훨씬 빠를 것 같습니다.
업데이트 2 :
아래의 다른 조언에 따라 jQuery.tmpl ( KnockOut 에서 기본적으로 지원됨)을 제공 했으며이 템플릿 엔진은 3 초 만에 약 400 개의 행을 그릴 것입니다. 스크롤 할 때 더 많은 데이터를 동적으로로드하는 솔루션이 부족한 가장 좋은 방법 인 것 같습니다.