22sook00 logo
SookDev
👀

intersection observer

01_자바스크립트 스크롤 이벤트의 한계

자바스크립트에서 무한스크롤 구현방법과 문제점
  • addEventListner() 에 scroll 이벤트 이용하여 구현 가능
  • getBoundingClientRect() 메서드로 원하는 특정위치에서 다음 페이지들을 가져오도록 구현
이 두개의 방법은 다음과 같은 이유로 성능문제를 발생시킨다.
scroll 이벤트 : 단시간에 수백번 호출이 되며 동기적으로 실행
getBoundingClientRect() : 엘리먼트크기와 뷰포트의 상대적인 위치 정보를 제공하는 dom 객체를 반환하여 우리가 원하는 특정 위치를 정할 수 있다. 하지만 계산을 할때마다 리플로우 현상이 일어난다.
리플로우 현상이란 ?
→ 문서 내 요소에 위치한 도형을 다시 계산하기 위한 웹브라우저의 프로세스 이름으로, 문서의 일부나 전체를 다시 렌더링 하는데 사용하는 개념
이 두개의 방법은 메인 스레드에서 실행이 되기 때문에 이 중 하나라도 호출되면 성능문제를 일으킬 수 있다.
그 대안으로 Intersection Observer 를 사용하여 비동기적으로 교차점을 관찰하여 성능을 개선 할 수 있다.
 
 

02_Intersection Observer 란?

브라우저 뷰포트와 원하는 요소의 교차점을 관찰하며, 요소가 뷰포트에 포함되는지 아닌지 구별하는 기능
notion image
  • 비동기적으로 실행되어 메인스레드에 영향을 주지 않으면서 요소들의 변경사항을 관찰한다.
    • scroll의 이벤트 연속호출의 문제와 getBoundingClientRect 의 성능문제 해결
  • intersectionObserverEntry 등 속성을 활용하여 요소들의 위치를 알 수 있다.
  • 여러상황에서 사용 가능
    • 페이지 스크롤 되는 도중 발생하는 이미지 지연 로딩
    • 자동으로 페이지 하단에 스크롤 했을 때 무한스크롤 구현
    • 광고 수익계산을 위한 광고 가시성 보고하기 위해 사용
 

03_Intersection Observer 기본문법

어떤 상황에서 콜백함수를 호출할까
  • 대상(target) 요소가 기기 뷰포트나 특정 요소와 교차할 때
  • 관찰자(observer) 가 최초로 타겟을 관측하도록 요청받을때
Intersection Observer() 는 new IntersectionObserver 라는 생성자를 통해 인스턴스를 만들고 시작한다.
해당 인스턴스로 관찰자를 초기하고 관찰할 대상을 등록하면 된다.
이때 콜백함수와 옵션, 이 두개의 인자를 갖는다.
  • callback : 관찰할 대상이 등록되거나 가시성에 변화가 생기면 실행. (entries=[], observer 두개의 인자를 가진다.)
  • Options : 관찰이 시작되는 상황에 대한 옵션을 설정할 수 있다. (root, rootMargin, threshold)
 
✳️ Intersection Observer Callback : Entry 속성
읽기전용의 여러가지 속성들을 포함
  • boundingClientRect : 관찰 대상의 경계 사각형을 DOMRectReadOnly 로 반환
    • getBoundingClientRect() 와 동일한 값을 얻으나 reflow 없이 계산한다는 점에서 차이가 있다.
      • notion image
  • intersectionRect : 관찰 대상의 교차한 영역 정보를 DOMRectReadOnly 로 반환
    • 뷰포트 안에 들어온 요소 정보만
      • notion image
  • intersectionRatio : 관찰 대상의 교차한 영역 비율을 0.0 과 1.0 사이의 숫자로 반환
    • 만약 상위 50% 라면 0.5, 상위 10%만 반환하면 0.1 이런식으로 반환된다.
      • notion image
  • isIntersecting : 관찰 대상이 교차 상태인지 아닌지 불리언값으로 반환
    • 뷰포트 내 하나라도 걸린다면 true 값을 반환하고 아니면 false 반환
      • notion image
  • rootBounds : 지정한 루트 요소의 사각형 정보를 DOMRectReadOnly 로 반환
    • 기본적으로 전체 뷰포트가 루트요소가 되고, rootMargin 값으로 루트 요소의 크기를 변경할 수 있다.
      • notion image
  • target : 관찰대상 요소(Element) 반환
  • time : 변경이 발생한 시간 정보 (DOMHighResTimeStamp) 반환
 
✳️ Intersection Observer Options
Options 를 통해 관찰이 시작되는 상황에 대한 옵션을 설정할 수 있다.
기본값이 있어 필수는 아니다.
  • root : 대상 객체(target) 의 가시성을 확인할 때 사용되는 뷰포트 요소. 반드시 대상 객체의 “조상” 요소여야 한다. 혹시 null || undefined 라면 브라우저의 뷰포트가 기본값으로 설정된다.
  • rootMargin : root가 가진 바깥 여백(Margin). margin 값(px, %)을 이용해 root 범위를 확장/축소 할 수 있다.
    • ex - 10px 20px 30px 40px (top,right,bottom,left) , default = 0
  • threshold : observer의 콜백이 실행될 대상요소(target) 의 가시성이 얼마나 필요한지 나타내는 값. 기본값은 0 이다.
    • 0인경우에는 타겟의 가장자리 픽셀이 루트범위를 바로 교차하는 순간 observer 가 실행된다.
    • 0.1 인 경우 타겟의 가시성이 10%일 경우 실행이 된다.
    • 배열안에 0, 0.2, 1 일 경우 타겟의 가시성이 0,20%,100%일때 observer 가 모두 실행이 된다.
 
✳️ Intersection Observer Method
  • observe : 대상 요소(target)의 관찰을 시작할 때 사용
  • unobserve : 대상 요소의 관찰을 중지할 때 사용. 관찰을 중지할 하나의 대상 요소를 인수로 지정해야 한다.
  • disconnect : intersectionObserver 인스턴스가 관찰하는 모든 요소의 관찰을 중지할 때 사용