TIL(22.05.12)

bu-geon·2022년 5월 12일
1

TIL

목록 보기
3/10
post-thumbnail

Infinite Scroll

방대한 양의 데이터를 한번에 가져오려면 용량도 너무 크고, 시간도 오래 걸린다. 따라서, 화면에 보여줄수 있는 적당한 단위로 나눠서 차례차례 가져오는 방법을 주로 사용한다. 주로 paginationinfinite scroll을 사용하는데, 모바일 웹과 일반 웹의 경계가 많이 허문 요즘에는 infinite scroll이 더 선호되는듯 하다.

Scroll Event


단순하게 스크롤 이벤트가 동작할때, client에게 실제로 보여주는 부분과 scroll로 감쳐진 부분을 더해서 전체 스크롤의 크기와 같은지 비교하는 방식이다. 구현하는 것은 간단하지만, scroll 이벤트시 많은 동작이 발생하기때문에, 디바운싱 혹은 쓰로틀링 같은 기법을 동원해서 빈번한 이벤트의 빈도를 핸들링할 수 있어야 한다.

IntersectionObserver & useRef

IntersectionObserver와 useRef를 활용한 방식은 react에서 사용하는 기법인데, 스크롤 최하단의 마지막 요소나, 연속적인 리스트 요소 아래에 인위적인 DOM을 하나 두워서 IntersectionObserver 객체가 client에게 보여질때 비동기 방식을 이용해서 추가적으로 데이터를 받아오는 동작을 트리거한다.

IntersectionObserver 생성


let options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);

IntersectionObserver() 생성자에 전달되는 options 객체는 observer 콜백이 호출되는 상황을 조작한다.

root
대상 객체의 가시성을 확인할 때 사용되는 뷰포트 요소(대상 객체의 조상 요소) 기본값은 브라우저 뷰포트, root 값이 null 이거나 지정되지 않을 때 기본값으로 설정
rootMargin
root 가 가진 여백. 이 속성의 값은 CSS의 margin 속성과 유사합니다. e.g. "10px 20px 30px 40px" (top, right, bottom, left). 이 값은 퍼센티지가 될 수 있다. root 요소의 각 측면의 bounding box를 수축시키거나 증가시키며, 교차성을 계산하기 전에 적용된다. 기본값은 0입니다.
threshold
observer의 콜백이 실행될 대상 요소의 가시성 퍼센티지를 나타내는 단일 숫자 혹은 숫자 배열입니다. 만일 50%만큼 요소가 보여졌을 때를 탐지하고 싶다면, 값을 0.5로 설정하면 됩니다. 혹은 25% 단위로 요소의 가시성이 변경될 때마다 콜백이 실행되게 하고 싶다면 [0, 0.25, 0.5, 0.75, 1] 과 같은 배열을 설정하세요.
기본값은 0이며(이는 요소가 1픽셀이라도 보이자 마자 콜백이 실행됨을 의미합니다). 1.0은 요소의 모든 픽셀이 화면에 노출되기 전에는 콜백을 실행시키지 않음을 의미.

회고

비동기적으로 작동할때 에러를 찾아내는 것은 너무 힘들다. 순서가 뒤죽박죽이라서 정확한 에러의 원인을 찾기가 애매하다.
오늘은 인피니트 스크롤과 input에서 검색 query를 현재 onChange 이벤트가 발생할때마다 api를 call하기 때문에 성능을 개선하고자 디바운싱을 해보려 했는데 실패했다. 인피니트 스크롤은 일단 구현은 했는데, 마지막 요소에서 다음 페이지만 불러와야하지만, 스크롤 속도가 빠르면 여러 페이지를 연속적으로 콜한다. 또한. 다음 페이지가 있는지 검사를 한 후에 api를 call 해야 하는데, 이 부분이 제대로 동작하지 않는지 다음페이지가 없어도 계속해서 page를 증가시켜가며 call을해서 수정이필요하다.
디바운싱은 조금이나마 높아졌던 리액트에 대한 내 자신감을 완적히 꺽어놨다. 이론은 쉽게 이해한데 반해서 구현할 방법이 도무지 떠오르지 않았다. 비동기적으로 그리고 리액트가 동작하는 방식을 아직 정확히 습득하지 못했기 때문인듯한데, 너무 암울하다.

0개의 댓글