code

무한 스크롤 또는 많은 dom 요소로 성능?

codestyles 2020. 11. 11. 20:13
반응형

무한 스크롤 또는 많은 dom 요소로 성능?


돔 elmenets 및 성능의 큰 #에 대한 질문이 있습니다.

한 페이지에 6000 개의 dom 요소가 있고 사용자가 트위터와 같은 페이지와 상호 작용할 때 (사용자가 스크롤하여 새 dom 요소를 생성 할 때) 요소 수를 늘릴 수 있다고 가정 해 보겠습니다.

페이지의 성능을 향상시키기 위해 두 가지만 생각할 수 있습니다.

  1. 리플 로우를 피하기 위해 보이지 않는 항목에 표시를 없음으로 설정
  2. DOM에서 보이지 않는 항목을 제거한 다음 필요에 따라 다시 추가하십시오.

DOM 요소가 많은 페이지를 개선하는 다른 방법이 있습니까?


이것에 대한 경험은 없지만 여기에 몇 가지 훌륭한 팁이 있습니다. http://engineering.linkedin.com/linkedin-ipad-5-techniques-smooth-infinite-scrolling-html5

나는 Facebook을 보았고 그들은 Firefox에서 특별히 아무것도하지 않는 것 같습니다. 아래로 스크롤해도 페이지 상단의 DOM 요소는 변경되지 않습니다. Firefox의 메모리 사용량은 Facebook에서 더 이상 스크롤 할 수 없게되기 전에 약 500 메가로 증가합니다.

Twitter는 Facebook과 동일한 것으로 보입니다.

Google지도는 다른 이야기입니다.보기에서 벗어난지도 타일은 DOM에서 제거됩니다 (즉각적인 것은 아님).


우리는 FoldingText 에서 유사한 문제를 다루어야했습니다 . 문서가 커짐에 따라 더 많은 선 요소와 관련 범위 요소가 만들어졌습니다. 브라우저 엔진이 질식하는 것처럼 보였으므로 더 나은 솔루션을 찾아야했습니다.

귀하의 목적에 유용하거나 유용하지 않을 수있는 작업은 다음과 같습니다.

전체 페이지를 긴 문서로 시각화하고 브라우저 뷰포트를 긴 문서의 특정 부분에 대한 렌즈로 시각화합니다. 렌즈 안에있는 부분 만 보여 주면됩니다.

따라서 첫 번째 부분은 보이는 뷰포트를 계산하는 것입니다. (이것은 요소 배치 방식, 절대 / 고정 / 기본값에 따라 다릅니다)

var top = document.scrollTop;
var width = window.innerWidth;
var height = window.innerHeight;

더 많은 브라우저 간 기반 뷰포트를 찾기위한 추가 리소스 :

JavaScript로 브라우저 뷰포트 크기 가져 오기

브라우저 창의 scrollTop을 감지하는 브라우저 간 방법

둘째, 해당 영역에 어떤 요소가 표시되는지 알기위한 데이터 구조가 필요합니다.

우리는 이미 텍스트 편집을위한 균형 잡힌 이진 검색 트리를 가지고 있었으므로 줄 높이도 관리하도록 확장했기 때문에이 부분은 비교적 쉬웠습니다. 요소 높이를 관리하기 위해 복잡한 데이터 구조가 필요하다고 생각하지 않습니다. 간단한 배열이나 객체가 괜찮을 수 있습니다. 높이와 치수를 쉽게 쿼리 할 수 ​​있는지 확인하십시오. 이제 모든 요소에 대한 높이 데이터를 어떻게 얻을 수 있습니까? 매우 간단합니다 (그러나 많은 양의 요소에 대해 계산 비용이 많이 듭니다!)

var boundingRect = element.getBoundingClientRect()

나는 순수 자바 스크립트의 관점에서 이야기하고 있지만, jQuery를 사용하는 경우 $.offset, $.position상장 및 방법 이곳은 매우 도움이 될 것입니다.

다시 말하지만 데이터 구조를 사용하는 것은 캐시로만 중요하지만 원하는 경우 즉석에서 수행 할 수 있습니다 (이 작업은 비용이 많이 든다고 언급했듯이). 또한 CSS 스타일을 변경하고 이러한 메서드를 호출하지 않도록주의하십시오. 이러한 함수는 강제로 다시 그리기 때문에 성능 문제가 발생합니다.

마지막으로, 화면 밖의 <div>요소를 단일 높이로 대체하십시오.

  • 이제 데이터 구조에 저장된 모든 요소의 높이가 있고 보이는 뷰포트 앞에 있는 모든 요소를 ​​쿼리합니다 .

  • <div>CSS 높이를 요소 높이의 합으로 (픽셀 단위) 설정 하여 만듭니다.

  • 필러 div를 알 수 있도록 클래스 이름으로 표시하십시오.
  • 이 div가 다루는 DOM에서 모든 요소를 ​​제거하십시오.
  • 대신 새로 만든 div를 삽입하십시오.

보이는 뷰포트 뒤에 있는 요소에 대해 반복합니다 .

스크롤 및 크기 조정 이벤트를 찾습니다. 각 스크롤에서 데이터 구조로 돌아가서 필러 div를 제거하고 이전에 화면에서 제거 된 요소를 만들고 그에 따라 새 필러 div를 추가해야합니다.

:) 길고 복잡한 방법이지만 큰 문서의 경우 성능이 크게 향상되었습니다.

tl; dr

제대로 설명했는지 모르겠지만이 방법의 요점은 다음과 같습니다.

  • 요소의 수직 치수 파악
  • 스크롤 된 뷰 포트 파악
  • 모든 오프 스크린 요소를 단일 div로 나타냅니다 (높이가 다루는 모든 요소 높이의 합과 같음).
  • 주어진 시간에 총 2 개의 div가 필요합니다. 하나는 보이는 뷰포트 위의 요소 용이고 다른 하나는 아래 요소 용입니다.
  • 스크롤 및 크기 조정 이벤트를 수신하여 뷰 포트를 추적합니다. 그에 따라 div 및 보이는 요소를 다시 만듭니다.

도움이 되었기를 바랍니다.


2019 년입니다. 질문은 정말 오래되었지만 여전히 관련성이 높고 흥미롭고 오늘날 우리 모두가 React JS를 사용하는 경향이 있기 때문에 오늘과 같이 변경되었을 수도 있습니다.

Facebook의 타임 라인은 display: none !important클러스터가보기에서 벗어나 자마자 숨겨지는 콘텐츠 클러스터를 사용하는 것으로 보이 므로 이전에 렌더링 된 DOM의 모든 요소는 DOM에 보관됩니다. display: none !important. 또한 숨겨진 클러스터의 전체 높이는 숨겨진 클러스터의 부모 div설정됩니다 .

내가 만든 스크린 샷은 다음과 같습니다.

enter image description here

enter image description here

enter image description here

As of 2019, what do you think about this approach? Also, for those who use React, how could it be implemented in React? It would be great to receive your opinions and thoughts regarding this tricky topic.

Thank you for the attention!

참고URL : https://stackoverflow.com/questions/12613113/performance-with-infinite-scroll-or-a-lot-of-dom-elements

반응형