무한 스크롤러의 복잡성

요약: DOM 요소를 재사용하여 표시 영역입니다. 자리표시자를 사용하여 지연된 데이터를 고려합니다. 이 demo 및 무한대의 코드가 스크롤러입니다.

인터넷 곳곳에 무한 스크롤러가 나타납니다. Google 뮤직의 아티스트 목록: 하나는 Facebook의 타임라인이고 Twitter의 실시간 피드도 하나의 타임라인입니다. 나 아래로 스크롤하면 하단까지 스크롤하면 마법처럼 새 콘텐츠가 나타납니다 당연한 것 같네요. 사용자에게 원활한 환경이며 확인할 수 있습니다

하지만 무한 스크롤러 뒤에 숨겨진 기술적인 문제는 다른 것보다 더 어렵습니다. 있습니다. The Right ThingTM을 실행할 때 발생하는 문제의 범위 방대합니다. 처음에는 바닥글에 있는 링크가 페이지 품질보다 실제로는 콘텐츠가 바닥글을 계속 밀어내기 때문에 실제로 도달할 수 없습니다. 하지만 문제는 더 어려워집니다. 다른 사용자가 휴대전화가 세로에서 가로로 흔들리지 않게 하려면 어떻게 해야 할까요? 목록이 너무 길면 끔찍한 중단이 발생할까요?

올바른 방법TM

이에 대한 참조 구현을 제시하기에 충분한 이유가 있다고 판단했습니다. 이 모든 문제를 재사용할 수 있는 방식으로 해결할 수 있는 성능을 개선하는 데 도움이 됩니다

목표를 달성하기 위해 세 가지 기술인 DOM 재활용, Tombstone을 사용하겠습니다. 스크롤 앵커링을 살펴보겠습니다

데모 케이스는 스크롤할 수 있는 행아웃과 유사한 채팅 창입니다. 파악할 수 있습니다. 가장 먼저 필요한 것은 무한한 채팅 소스입니다. 메시지를 보낼 수 있습니다 엄밀히 말해서 무한 스크롤러 중에 실제로 무한하지만, 이러한 한계에 집중하기 위해 사용할 수 있는 데이터의 양이 스크롤러도 될 수 있습니다. 여기서는 간단하게 채팅 메시지를 볼 수 있으며 에서 메시지, 작성자 및 가끔씩 이미지 첨부 파일을 선택합니다. 인위적인 지연을 조금씩 가미하여 실제 네트워크입니다.

채팅 앱 스크린샷

DOM 재활용

DOM 재활용은 DOM 노드 수를 낮게 유지하는 데 잘 활용되지 않는 기술입니다. 이 일반적으로 이미 만들어져 화면 밖에 있는 DOM 요소를 대신 사용하는 것입니다. 새로운 것을 만들 수 있습니다. 물론 DOM 노드 자체는 저렴하긴 하지만 각각 메모리, 레이아웃, 스타일 및 페인트에 추가 비용이 발생하기 때문입니다. 저사양 기기는 웹사이트에 DOM이 너무 커서 관리할 수 없습니다. 또한 레이아웃이 변경될 때마다 스타일을 다시 적용하는 과정입니다. 이 프로세스는 클래스가 노드에서 추가되거나 제거됨 – DOM이 클수록 비용이 더 많이 듭니다. DOM 노드를 재활용하면 총 DOM 수를 노드 수가 상당히 낮기 때문에 이러한 모든 프로세스가 빨라집니다.

첫 번째 장애물은 스크롤 자체입니다. 아주 작은 하위 집합만 사용할 것이므로 DOM에서 사용 가능한 모든 항목을 한 번에 처리하려면 다른 방법을 스크롤바가 스크롤을 내려야 하는 찾을 수 있습니다. 1px x 1px 센티널 요소를 변환과 함께 사용하겠습니다. 항목이 포함된 요소(활주로)에 원하는 높이. 런웨이의 모든 요소를 자체 레이어로 승격하여 활주로 자체의 층이 완전히 비어 있도록 합니다. 배경 색상 없음, 없습니다. 활주로의 레이어가 비어 있지 않으면 브라우저의 그래픽 카드에 텍스처를 저장해야 하므로 수십만 픽셀 높이입니다. 특정 시점에는 있습니다.

스크롤할 때마다 표시 영역이 활주로가 끝났음을 의미합니다. 그렇다면 보초를 이동하여 이 활주로를 연장할 것입니다. 요소를 표시하고 표시 영역에서 나간 항목을 새로운 콘텐츠로 채울 수 있습니다.

<ph type="x-smartling-placeholder"></ph> <ph type="x-smartling-placeholder"></ph> 런웨이 센티널 에 대해 자세히 알아보세요. 표시 영역

다른 방향으로 스크롤할 때도 마찬가지입니다. 하지만 스크롤바 위치가 유지되도록 구현에서 런웨이를 축소합니다. 일관성이 있어야 합니다.

Tombstone

앞서 언급했듯이 데이터 소스가 다른 것 처럼 동작하도록 이야기해 보겠습니다. 네트워크 지연 시간 등 모든 기능이 포함됩니다. 즉, 만약 사용자는 플리시 스크롤을 활용하여 마지막 요소를 지나 쉽게 스크롤할 수 있습니다. 확인할 수 있습니다. 이 경우 Tombstone 항목( 자리표시자가 있습니다. 데이터가 도착했습니다. Tombstone도 재활용되며 비석을 위한 별도의 풀이 있음 재사용 가능한 DOM 요소를 사용합니다. 새로운 환경에서 원활하게 전환하려면 내용으로 채워진 항목에 삭제 표시를 합니다. 그렇지 않으면 사용자가 자신이 무엇을 감상했는지 잊어버릴 수 있습니다 초점을 맞추고 있습니다.

이러한
무덤이 있습니다. 아주 돌이라. 와우

여기서 흥미로운 문제는 실제 항목의 높이가 다른 항목보다 클 수 항목당 텍스트 양이 다르기 때문에 또는 첨부된 파일에 이미지 이 문제를 해결하기 위해 매번 현재 스크롤 위치를 조정합니다. 데이터가 수신되고 표시 영역 위에서 Tombstone이 교체되어 고정 스크롤 위치를 픽셀 값이 아닌 요소로 설정합니다. 이 개념은 스크롤 앵커링이라고 합니다

스크롤 고정

스크롤 앵커링은 Tombstone이 다른 상태로 교체되는 경우 모두 호출됩니다. 창의 크기가 조절될 때뿐만 아니라 (기기가 창을 다시 열 때) 있습니다!) 가장 위에 표시되는 요소가 무엇인지 확인할 수 있습니다 이 요소는 일부만 표시될 수 있으므로 는 표시 영역이 시작되는 요소 상단으로부터의 오프셋을 저장합니다.

스크롤 고정 다이어그램

표시 영역의 크기가 조절되고 활주로가 변경되면 사용자와 시각적으로 동일하게 느껴지는 상황을 말합니다. 승리! 크기가 조정된 각 항목의 높이가 변경되었을 수 있습니다. 그렇다면 각 항목의 높이를 앵커 콘텐츠를 얼마나 아래쪽에 배치해야 하는지 알고 있나요? 그렇지 않습니다. 알아보기 위해 앵커 항목 위에 있는 모든 요소를 배치하고 그들의 높이, 크기를 조절한 후 상당한 일시중지가 발생할 수 있으며 있습니다. 대신 위의 모든 항목이 동일한 크기라고 가정합니다. 이에 따라 스크롤 위치를 조정합니다. 요소는 활주로로 스크롤하면 스크롤 위치를 조정하여 실제로 필요할 때 레이아웃이 작동합니다.

레이아웃

중요한 세부사항인 레이아웃은 건너뛰었습니다. DOM 요소의 각 재활용 일반적으로 활주로 전체를 다시 배치하여 초당 60프레임을 목표로 삼고 있습니다. 이를 방지하기 위해 Google은 직접 배치하고 변환과 함께 절대 위치에 있는 요소를 사용합니다. 이런 식으로 우리는 활주로 더 위쪽에 있는 모든 요소들이 여전히 움직이고 있다고 실제로 빈 공간만 있을 때 공간을 차지합니다. 이 과정에서 각 항목이 끝나는 위치를 캐시하고 사용자가 뒤로 스크롤하면 캐시에서 올바른 요소가 즉시 로드됩니다.

항목이 DOM에 연결될 때 한 번만 다시 페인트하는 것이 이상적입니다. 런웨이에서 다른 물품이 추가 또는 삭제되어도 당황하지 않도록 해야 합니다. 즉 최신 브라우저에서만 가능합니다.

최신 수정

최근 Chrome은 CSS 포함 지원을 추가했습니다. 이를 통해 개발자는 요소가 요소의 경계임을 브라우저에 알 수 있습니다. 사용됩니다. 여기서 레이아웃 작업을 하고 있기 때문에 격리시킬 수 있습니다 런웨이에 요소를 추가할 때마다 항상 알게 됩니다 다른 항목은 재레이아웃의 영향을 받지 않아도 됩니다. 따라서 각 항목은 contain: layout가 됩니다. 또한 웹사이트의 나머지 부분에도 영향을 주지 않으려고 합니다. 런웨이 자체에도 이 스타일 지침이 있어야 합니다.

또 다른 고려 사항은 감지하기 위한 메커니즘으로서 IntersectionObservers 사용자가 요소를 재활용하기 시작할 수 있을 정도로 충분히 스크롤했고 데이터를 수집하는 데 사용됩니다 그러나 IntersectionObserver는 높은 지연 시간으로 지정됩니다 (예: requestIdleCallback를 사용하는 경우) IntersectionObservers를 사용하지 않습니다. 심지어 scroll 이벤트에 이 문제가 발생합니다. 스크롤 이벤트가 '최선의 노력'을 기반으로 합니다. 결국 Houdini의 컴포지터 Worklet은 이 문제에 대한 충실도가 높은 솔루션이 될 것입니다.

아직 완벽하지 않음

현재 구현된 DOM 재활용은 모든 요소를 추가하므로 이상적이지 않습니다. 통과하는 모든 이미지를 표시할 수 있습니다. 실제로 화면에 표시됩니다. 즉, 매우 빠르게 스크롤하면 Chrome에서는 레이아웃과 페인트에 너무 많은 작업을 해야 하므로 따라잡을 수 없습니다. 종료 배경만 보입니다. 세상의 종말이 아닌 확실히 개선의 여지가 있습니다.

간단한 도전과제가 얼마나 어려운지 우수한 사용자 경험과 높은 성능 표준을 결합합니다. 다음으로 바꿉니다. 프로그레시브 웹 앱이 휴대전화의 핵심 환경이 됨에 따라, 점점 더 중요해지고 있으며 웹 개발자들은 성능 제약 조건을 준수하는 패턴을 사용하여

모든 코드는 Google 저장소에서 찾을 수 있습니다. 우리는 해냈어 재사용 가능한 상태로 유지하기는 하지만, npm 또는 별도의 저장소로 사용할 수 있습니다. 주된 용도는 교육입니다.