어때? 예를 들어, 렌더링하고자하는 viewModel.items = ko.observableArray()
이 있다고 가정 해보십시오.
- 관찰 할 수없는 데이터 배열 (예 :
var itemsToRender = functionThatReturnsLargeArray()
)이 있습니다.
itemsToRender
의 데이터 일부를 관찰 가능한 배열에 넣으십시오. 50 개 요소 만 말해봐.
setTimeout
콜백 내부의 부분에 관찰 가능한 배열에 요소를 계속 추가합니다.
주 1 : 당신은 약간의 시간 추적 setTimeout
콜백 및 증가에/당신이 각 반복에 추가 할 항목의 수를 줄일 추가 할 수 있습니다. 귀하의 목표는 각 콜백 시간을 50-100 밀리 초 이하로 유지하여 응용 프로그램이 여전히 반응이 느껴지도록하는 것입니다.
var batchSize = 50; // default number of items rendered per iteration
var batchOffset = 0;
function render(items, itemsToRender, done) {
setTimeout(function() {
var startTime = new Date().getTime();
items.pushAll(itemsToRender.slice(batchOffset, batchSize));
batchOffset += batchSize;
// at this point Knockout rendered next batchSize items from itemsToRender
var endTime = new Date().getTime();
// update batchSize for next iteration
batchSize = batchSize * 50/(endTime - startTime); // 50 milliseconds
batchSize = Math.min(itemsToRender.length, batchOffset + batchSize);
if (batchSize > 0) render() else done(); // callback if you need one
}, 0);
}
/* I haven't actually tested the code */
다른 배치 크기 업데이트 전략은 대상 FPS를 기반으로 할 수 있습니다. 60fps의 업데이트 속도를 얻고 싶다고 가정하면 1000 밀리 초당 setTimeout
번의 60 회의 통화가 가능합니다. 전체 컬렉션을 처리하는 데 다소 시간이 걸릴 것입니다. setTimeout
대신 requestAnimationFrame
을 사용하고 어떻게 작동하는지 확인할 수도 있습니다.
편집 : Build-in throttling이 Knockout JS 1.3에 추가되었다 (현재는 베타 버전입니다하지만 꽤 안정적인 것 같습니다).
NOTE2 : 뷰에 다른 데이터가 viewModel.items
에 의존하는 경우 당신은 여전히 원래의 배열 itemsToRender
에 아래로 매핑 할 수 있습니다. 예를 들어 수집 할 항목 수를 표시하려고한다고 가정 해보십시오. viewModel.items().length
을 사용하면 더 많은 항목이 렌더링되는 동안 UI에서 크기 값이 변경되므로 결국됩니다. 이를 방지하려면 먼저 itemsToRender
을 기준으로 dependentObservable
으로 크기 바인딩을 정의해야합니다 (viewModel.items
이 아님).모든 항목을 렌더링 한 후에는 적합하다고 생각되면 viewModel.items
에 다시 매핑 할 수 있습니다.
다음은이 문제를 보여줍니다. http://jsfiddle.net/DESC3/10/ 요점을 확인하는 데 필요하지 않으므로 데이터 양이 줄어 듭니다. – Esailija
다음은 동일한 html (2000 행)이 다른 접근 방식으로 즉시 렌더링되는 방법입니다 (http://jsfiddle.net/DESC3/11/). 나는 이것을 말하는 것이 아니라 단지 녹아웃이 매우 최적화되어 있지 않다는 것을 보여줍니다 ... – Esailija
@Esailija - 첫 번째 예는 실제로 실제로 빠릅니다. 이것은 1000 행 이상일 때만 우리에게 문제가됩니다. 모든 데이터를 하나의 데이터로 가져 오는 데는 몇 가지 이유가 있습니다. 따라서 페이지 매기기 또는 청크로 데이터를 보내는 것은 실제로 선택 사항이 아닙니다. – RyanScottLewis