[Day 28] Intersection Observer

thru·2023년 7월 26일
2

FEDC-TIL

목록 보기
19/21

Avoid Intersection Observer

오늘 공부한 내용 🌧️

무한 스크롤과 이를 구현하는 방법을 배웠다.


새로 알게된 내용 🌱

더보기 버튼

더보기 버튼으로 데이터를 수동으로 가져오는 게 때에 따라 나을 수도 있다는 내용이 있어 찾아보았다.

일단 다량의 데이터 목록을 순차적으로 보여주는 방법에는 크게 세 가지가 있다.

페이지네이션

페이지네이션은 화면에 한 페이지에 해당하는 데이터를 보여주고 다른 데이터는 보통 하단의 페이지 번호와 이전/이후 페이지 버튼 네비게이션을 통해 이동하는 방식이다. 워낙 옛날 사이트에서도 쓰던 방식이라 익숙하다.

장점

  • 페이지 레이아웃을 해치지 않아 footer 같은 요소에도 사용자가 쉽게 접근할 수 있다.
  • 쉽게 스크롤해서 넘겨버리거나 할 수 없으니 개별 데이터에 대한 집중도가 높다.

단점

  • 페이지를 넘기려면 보통 커서를 움직여서 조그만 버튼을 클릭해야 하다 보니 사용자가 데이터를 더 보지않고 이탈하는 경우가 잦다.
  • 모바일에서는 클릭하기 힘들 수 있다.

때문에 보통 상품을 계속 보여줘야하는 커머스에서는 잘 안쓴다. 대신 목록 중에 알맞는 검색 결과를 놓치지 않게 하는 것이 바람직한 검색 사이트에서 주로 사용한다.

더보기 버튼

데이터 목록 최하단에 더보기 버튼을 배치하고 사용자가 누르면 다음 목록을 보여주는 방식이다.

장점

  • 사용자가 footer에 비교적 쉽게 접근할 수 있다.
  • 그냥 쫙 스크롤해서 다량의 데이터를 넘겨버리는 것을 일부 방지할 수 있다.

단점

  • 여전히 데이터 로드를 위해 적극적인 클릭이 필요하다.
  • 무한 스크롤 보다는 사용자가 이탈 전까지 보는 데이터 양이 통계적으로 적다.

무한 스크롤

목록에 하단에 스크롤이 오면 자동으로 인식해서 다음 목록을 불러오는 방식이다.

장점

  • 사용자가 가장 많은 데이터를 보는 방식
  • 전체 데이터를 신속하게 표시할 수 있다.

단점

  • footer에 사실상 접근할 수 없다.
  • 스크롤 바가 과하게 짧아질 수 있다.
  • 막힘 없는 스크롤로 일부 데이터를 스킵하고 넘어갈 가능성이 높다.

더보기 버튼과 무한 스크롤은 화면이 작은 모바일 환경에 최적화된 방식이라 근래부터 많이 쓰인다.
다만 어느 한 가지 방법이 무조건 우위에 있는 것은 아니고 두 가지를 섞어쓰는 게 효과적이라고 한다.

데이터를 큰 구간과 작은 구간으로 나눠서 작은 구간 사이에서는 무한 스크롤을 사용하고 큰 구간에서는 더보기 버튼을 사용할 수 있다. 이 방법으로 둘의 단점을 일부 상쇄할 수 있다.

개발자한테는 무한 스크롤이 가장 최신 기술이다보니 무조건 다른 기술보다 우위에 있다고 착각하는 경우가 생기는 것 같다.
못을 알려주고 다음에 나사를 알려주면 모든 것에 나사를 쓰려고 하는 그런 느낌인 것 같다.


리마인드된 내용 🔨

Intersection Observer

요소의 가시성을 탐지하는 방법은 3단계로 발전해왔다고 볼 수 있다.

scroll 이벤트

window의 scrollYinnerHeight, 요소의 clientHeight 등의 인스턴스 속성을 사용해서 스크롤 위치와 비교하거나Element.getBoundingClientRect() 메서드를 호출해서 뷰 포트와의 상대적 위치를 이용하는 방식으로 intersection을 확인 할 수 있다.
해당 로직을 scroll 이벤트에 등록해주면 스크롤 때마다 요소가 뷰 포트에 탐지되는지 검사할 수 있다.

단점으로는 메인 스레드에 부담이 크다는 것이다. 이벤트 핸들러 자체는 매크로 태스크 큐에 들어가 이벤트 루프를 막지는 않는다. 그러나 차례가 와서 돌아갈 때 메인 스레드에서 요소의 탐지 로직과 탐지 후 실행하고자 하는 로직 모두를 실행해야 한다. 스크롤 이벤트는 스크롤 하는 중에 계속 발생하므로 메인 스레드에 과다한 로직이 투입된다.

또한 reflow를 추가로 발생시켜 부담을 더할 수 있다. 브라우저는 보통 최적화를 위해 reflow를 유발하는 사항을 큐에 쌓아서 한 번에 처리해 reflow의 발생 수를 최소화하고자 한다. 그러나 위치 값을 정확히 읽어들이기 위해서는 큐에 쌓여있던 reflow 유발 사항을 모두 flush하고 스타일을 적용해야한다. 스크롤 이벤트마다 요소를 탐지하면 reflow도 마찬가지로 계속 발생하여 성능에 문제를 야기한다.

디바운스, 쓰로틀링

때문에 이벤트 핸들러의 호출 빈도를 줄이고자 setTimeout 을 활용한 기법이 사용된다. 보통 스크롤 이벤트에서는 호출 간격을 조절하는 쓰로틀링을 주로 사용한다.

단, 빈도가 줄었을 뿐 탐지 로직이 메인 스레드에서 발생하는 것은 동일하다. 또한 setTimeout 자체도 태스크 큐에 들어가 처리되는 함수이므로 콜 스택이 비워져야 실행될 수 있어 실행 간격을 정확히 보장할 수 없다.

Intersection Observer API

기존에는 위 방법들이 계속 쓰이고 있었지만 사용 빈도가 높아지면서 신뢰도 높은 공식 API의 필요성이 대두되면서 만들어졌다.

16년 4월에 소개되었다는데 그 전까지 계속 저런 걸?

Intersection Observer는 탐지하고자 하는 요소가 다른 요소에 교차할 때 콜백 함수를 등록할 수 있게 한다. 이는 이전 방법들과 다르게 비동기적으로 일어나고 탐지 로직에 메인 스레드를 할애할 필요가 없어진다.

또한 탐지 대상 요소는 Element.getBoundingClientRect처럼 요소가 포함된 최소 크기의 사각형으로 탐지하며 이에 대한 위치 정보에 접근할 수 있지만 reflow를 발생시키지 않는다.

그렇다고 꼭 Intersection Observer가 이전 방법들의 상위 호환은 아니라고 한다.

이런 탐지 기능은 광고 노출 보고를 보낼 때도 사용한다. 이는 서버와의 요청이므로 하나하나 처리하는 것보다 모아서 처리하는 것이 좋다. 또한 사용자가 고속으로 스크롤해서 확인도 안하고 넘어간 광고를 거를 필요가 있다. 이를 위해선 사용자가 스크롤링을 멈췄을 때를 판단해 처리하는 것이 좋은데 Intersection observer는 교차만을 탐지하기 때문에 활용하기 어려워 이벤트 기반의 로직을 사용한다고 한다.


느낀점 🎬

개발자 입장에서 최신에 멋져보이는 기술이라 해서 모든 걸 해결 해주지는 않는다는 것을 알았고 때문에 차근차근 단계적으로 기술을 배우는 게 도움이 되겠다는 생각이 든다.

과제 마감에 쫓기다가 이제서야 쓰는데 이걸 TIL이라고 부를 수 있을까.. "오늘 공부한 내용" 옆에 원래 그날 날씨를 붙이는데 기억이 안난다. 어쩌피 비왔겠지 싶어서 그냥 비 이모티콘을 붙였다.


참조


profile
프론트 공부 중

1개의 댓글

comment-user-thumbnail
2023년 7월 26일

좋은 정보 얻어갑니다, 감사합니다.

답글 달기