Infinity Scroll
- Virtual Scroll을 알기 전에 Infinity Scroll (무한 스크롤) 에 대해서 알고 있으면 이해가 쉽다. 웹 상에서는 데이터를 불러와서 DOM 요소를 생성해 화면에 렌더링하는데, 정보를 한꺼번에 가져와서 보여주기에 정보량이 너무 많아 API Fetch로 받는 결과가 느릴 때, 스크롤을 통해 일부부만 가져와 보여주고 스크롤하면 추가로 보여주는 기술이자 인터페이스라고 한다.
- 기본적인 원리는 Scroll의 End 지점에 도달하면 추가 정보를 Fetch 하는 방식이다.
무한 스크롤 구현하는 방법
무한 스크롤을 구현하는 방법으로는 크게 2가지가 있다. 각 방법에 대해 자세하게 설명해놓은 블로그들이 많으니 한번 찾아보고 공부해보자. (요새 세상이 참 좋다..)
1. Scroll Event
2. Intersection Observer
다음에 요 Intersection Observer API를 활용해 직접 무한스크롤을 만들어보고 후기를 올리겠다.
자, 다시 이 글의 주제로 돌아오겠다.
Virtual Scroll
❔Vritual Scroll에 도전하게 된 이유
- 사실 해당 기능에 대해 이직을 준비하면서 모 기업의 과제 전형으로 유사한 내용을 구현하면서 알게 되었다. 인피니트 스크롤을 구현해보려고 다른 운영중인 서비스들을 참고했었는데, 그 때 우연히 지그재그 서비스를 살펴보면서 해당 기능이 있다는 것을 알 수 있었다.
본격적으로 Virtual Scroll!
Virtual Scroll이란 사용자에게 실제로 보이지 않는 컴포넌트는 렌더링하지 않고 영역만 차지하고 있다가 Scroll이 되면 사용자가 볼 수 있는 Viewport에 있는 요소만 실질적으로 렌더링 하는 기법! ('windowing' 기법이라고도 한다.)
- 기존 List 형식의 레이아웃에서 인피니트 스크롤의 경우, 스크롤을 내릴 수록 많은 DOM요소를 렌더링해야하여 성능이 떨어지는 이슈가 발생한다. 이를 해결하고자 나온 것이 Virtual Scroll 이라고 한다.
- 프론트엔드의 대표적인 라이브러리! React 에는 이 Virtual Scroll을 만들어 볼수 있는 라이브러리가 이미 존재한다. react-window, react-virtualized 이다. 필자는 Vanilla JS 로 구현하는 것이 목적이었으므로 해당 라이브러리를 활용한 개발은 다음에 해보기로 하겠다..
- 참고한 블로그 2가지 링크를 공유하겠다. 방법에 대해 너무나도 상세하게 기술되어 있어서 너무나도 많은 도움을 받았다ㅠ 너무감사합니다. (블로그1, 블로그2)
구현 과정
1. Content Container 높이 구하기
2. Index Range 범위 구하기
3. Index Range 포함 요소를 DOM Tree에 붙이기
4. Viewport의 높이를 translateY로 적용하기
1. Content Container 높이 구하기
Container의 높이는 '한 행의 높이' X '전체 데이터 개수'로 지정
const rowHeight = 42; // 각 행의 높이
const dataCount = userData.length; // data0 ~ data9까지 모든 데이터의 개수
const totalContentHeight = rowHeight * dataCount; // 전체 container의 높이 (420000)
2. Index Range 범위 구하기
StartIndex, EndIndex 를 구한다.
let startIndex = Math.max(Math.floor(offsetY / rowHeight) - nodePadding, 0); // 최소 데이터 개수보다 적을 수 없음.
let endIndex = Math.min(
dataCount,
Math.ceil((height / rowHeight) * 2 + startIndex) + nodePadding // 내 리스트는 2열이었기 때문에 2를 곱했다.
); //최대 데이터 개수보다 많을 수 없음.
3. Index Range 포함 요소를 DOM Tree에 붙이기
Index Range 안의 Item 들만 DOM Tree에 렌더링한다.
const container = document.querySelector('.container');
const item = document.createElement('li');
item.setAttribute("row-index", ${index 번호});
item.textContent = ${데이터 내용};
// 마지막 노드 뒤에 붙여준다.
const $next = Array.from(
document.querySelector(".content").childNodes
).find(($row) => index < Number($row.getAttribute("row-index")));
container.insertBefore(item, $next);
4. Viewport의 높이를 translateY로 적용하기
Container의 y축을 translateY값을 적용시켜준다.
const translateY = Math.max(rowHeight * startIndex, 0);
$content.style = `transform : translateY(${translateY}px)`;
결과물!
- 상세한 코드나 결과 내용에 대해 올릴수는 없지만, 이정도는 가능할 것같다. 인증샷정도로 생각!
마치며...🌱
이렇게 Virtual Scroll을 다양한 온라인 튜터들의 도움을 받아 만들어 봤다. 아쉽게도 해당 기업에서 원하는 기능은 아니었던지 합격하진 못했지만.. 많은 것을 배울 수 있었다. 정확하게 어떤게 다른지 알려주시면 좋았겠지만..하하하
Virtual Scroll을 나름 직접 구현해보면서 좀 더 스크롤 이벤트에 대해서 이해해볼 수 있어서 재밌었고, 다양한 예외케이스들에 대해서도 생각해볼 수 있었다. 좀더 능력있는 프론트엔드 개발자로서 성장해야겠다!
'🙆♀️ FE > JavaScript' 카테고리의 다른 글
Javascript 로 간단한 채팅 앱 만들기! (0) | 2024.07.03 |
---|---|
Event Capture & Event Bubble (0) | 2021.03.17 |
javascript30-04 (0) | 2021.02.27 |
javascript30-03 (0) | 2021.02.27 |
javascript30-02 (0) | 2021.02.25 |