2012-04-14 3 views
5

웹 페이지에는 제품 카드 (이미지와 텍스트가 포함 된 제품 카드) 목록이 아주 많습니다. 약 1000 개입니다. 클라이언트에서이 목록을 필터링하고 싶습니다 (필터링되지 않은 항목 만 표시되어야 함). 그러나 렌더링 성능 문제가 있습니다. 매우 좁은 필터를 적용하고 10-20 개의 항목 만 남은 다음 취소 (모든 항목을 다시 표시해야 함)하고 브라우저 (매우 멋진 컴퓨터의 Chrome)가 2 ~ 2 분 동안 중단됩니다.javascript를 사용하여 대량의 DOM 요소를 최적으로 렌더링하는 방법은 무엇입니까?

나는 다음과 같은 일상적인 사용하여 목록을 렌더링 재 :

for (var i = 0, l = this.entries.length; i < l; i++) { 
    $(this.cls_prefix + this.entries[i].id).css("display", this.entries[i].id in dict ? "block" : "none") 
} 

DICT 허용 항목의 식별자

자체가 즉시 실행이 기능의 해시, 그것은 그 렌더링 것은 끊습니다. DOM 요소의 "표시"속성을 변경하는 것보다 더 최적의 재 렌더링 방법이 있습니까?

미리 답변 해 주셔서 감사합니다.

+1

1000 개의 요소를 다시 렌더링하는 데 1 ~ 2 초가 걸립니까? 나는 1000 개의 요소가 언제든지 모두 보이지 않을 것이므로 아마도 보이는 항목을 처리 한 다음 백그라운드에서 작업하여 나머지를 사용할 수있게 할 것입니다 (각 배치 사이에 setTimeout()을 사용하여 패스 당 50 개를 수행하여 브라우저를 활성 상태로 유지). 또는 스크롤링으로 인해 실제로 표시 될 때만 다시 렌더링해야합니다. 또한 전체 DOM을 검색해야하는 1000 개의 별도의 선택기 연산을 실행하는 데 도움이되지 않습니다. – jfriend00

+0

작업 할 jsFiddle을 주면 스위치 오버 성능을 10 배 향상시킬 수있을 것이라고 확신합니다. 그 코드에는 많은 육즙이 많은 지방이 있습니다. – jfriend00

답변

4

1000 개 항목을로드하는 이유는 무엇입니까? 먼저 페이지 매김과 같은 것을 고려해야합니다. 페이지 당 약 30 개의 항목 표시. 그런 식으로, 당신은 많이로드하지 않습니다.

그런 다음 "루프가 많은 항목"이라면 시간 초과 사용을 고려하십시오. here's a demo 나는 한 번 그 루핑의 결과를 보여 주었다. UI를 차단하고 특히 긴 루프에서 브라우저가 지연 될 수 있습니다. 하지만 타이머를 사용하면 각 반복을 지연시켜 브라우저가 한 번 숨을 쉬고 다음 반복이 시작되기 전에 다른 작업을 수행 할 수 있습니다.

또 다른주의해야 할 점은 repaints and reflows을 피해야한다는 것입니다. 이는 필요하지 않을 때 요소 주위를 이동하거나 스타일을 변경하지 않는 것을 의미합니다. 또 다른 팁은 DOM에서 실제로 보이지 않는 노드를 제거하는 것입니다. 표시 할 필요가없는 경우 제거하십시오. 왜 실제로는 보이지 않는 무언가를 넣는 것을 낭비하지 않습니까?

+1

'리플 로우'팁을 보내 주셔서 감사합니다. - 저와 같은 초보자라도이 멋진 브라우저의 기계에 대해 알지 못하는 것은 용서할 수 없습니다. DOM에서 목록의 컨테이너를 제거하고 요소의 표시 속성을 변경 한 다음 컨테이너를 DOM에 다시 반환했습니다. Voila, 리플 로우 없음 - 끊지 마세요! –

-3

Dude - "많은 양의 DOM 요소"를 처리하는 가장 좋은 방법은 클라이언트에서 사용하지 않는 것 또는 자바 스크립트를 사용하지 않는 것이 좋습니다.

더 좋은 해결책이 없다면 (아마도 나는있을 것입니다!), 그리고 나서 작업 세트를 실제로 그 순간에 표시해야 할 작업으로 분할하십시오 (전체, 큰, 대신에, 재미있는 'enchilada !)

+3

나는 클라이언트에서/자바 스크립트를 사용하여 다량의 DOM 요소를 처리 할 때 반드시 잘못된 것은 없기 때문에 대답을 축소했습니다.평균 컴퓨터는 알고리즘, 리플 로우 등의 복잡성을 최소화 할 경우 초당 수만 가지 요소를 포함하는 DOM 업데이트를 처리 할 수 ​​있습니다. 실제로는 서버 왕복보다 훨씬 신속하게 대응할 수 있습니다 특히 클라이언트가 서버에서 제공 한 HTML을 사용하여 DOM을 계속 업데이트하게 될 것이기 때문입니다. 문제는 JavaScript가 아니라 사용 방법에 있습니다. –

+1

클라이언트 측 렌더링을 위해 2014 년에 '자바 스크립트 사용 안함'이라고 말하면 매우 나쁩니다. 특히 Google, Mozilla, Microsoft 등이 매년 수백만 달러를 투자하여 최종 사용자에게 WEB를 더 빠르고 더 좋게 무료로 제공 할 때. 어쩌면 최신 거래 응용 프로그램, 클라우드 솔루션, 음악 플레이어, CAD 및 그래픽 응용 프로그램, 거대한 상점 (필요한 경우 이름 지정)에 대해 무료로 다운로드 할 수있는 브라우저가 필요한 이유 일 것입니다. – Martin

0

setTimeout 트릭을 사용하면 기본 스레드의 루프 호출을 오프로드하여 클라이언트가 멈추지 않도록 할 수 있습니다. 처음부터 끝까지 - - 나는 총 처리가 의심 같은 시간을 마지막으로,하지만 적어도이 방법은 인터페이스가 여전히 사용할 수 있으며, 그 결과는 더 나은 사용자 경험 : 당신은 놀랄 것

for (var i = 0, l = this.entries.length; i < l; i++) { 
    setTimeout(function(){ 
    $(this.cls_prefix + this.entries[i].id).css("display", this.entries[i].id in dict ? "block" : "none") 
    }, 0); 
}