옵저버 패턴

이재철·2022년 6월 26일
0
post-thumbnail

옵저버 패턴?


데이터 종속적인 인터페이스가 데이터의 변화를 감시하는 구조

RxJS(Reactive Extensions For JavaScript) 없이, 웹 브라우저에서 제공하는 옵저버

  • IntersectionObserver: 루트 영역(뷰포트)와 대상 객체의 겹침을 감시
  • MutationObserver: 객체의 속성 변경을 감시
  • PerformanceObserver: 프로세스 성능 모니터링
  • ReportingObserver: 웹 사이트의 표준 및 정책 준수 현황을 감시
  • ResizeObserver: 객체의 너비, 높이의 변화를 감시

Intersection Observer


개념

특정 DOM 객체가 우리가 보는 화면 영역(viewport)와 겹치는 교차 이벤트를 감시

기존 문제점 및 장점

1. 문제점

  • scroll 이벤트는 단시간 수백번 ~ 수천번 호출, 동적으로 실행하므로 메인 스레드에 영향을 줌
  • 여러 scroll 이벤트가 등록되어 있는 경우 스크롤 할때마 이를 감지하는 이벤트가 끊임없이 호출 (디바운싱,쓰로틀링을 통해 이런 문제를 개선 가능)
  • 특정 지점을 관찰하기 위해서는 getBoundingClientRect() 함수 사용
    -> 이 함수는 리플로우(reflow) 현상이 발생하는 단점

2. 장점

  • 성능 향상 : 페이지 초기 로딩 시 필요한 요소들의 수를 줄여 불필요한 리소스 방지
  • 비용 감소 : 상단 부분만 사용하는 유저에게 최적화된 웹 사이트 제공

사용 예시

  • 페이지가 스크롤 되는 도중 발생하는 이미지나 다른 컨텐츠 지연 로딩 (Lazy Loading)
  • 무한 스크롤 구현 (infinite-scroll)
  • 광고 수익을 계산하기 위한 용도 (광고 가시성 보고)
  • 사용자에게 결과 표시 여부에 따른 작업이나 애니메이션을 수행할 지 여부 결정

Intersection Observer Api 사용법

Intersection Observer API는 타겟 엘리먼트가 조상 엘리먼트, 또는 최상위 문서의 뷰포트(브라우저에서는 보통 브라우저의 viewport)의 교차영역에서 발생하는 변화를 비동기로 관찰하는 방법을 제공합니다.
참고 : MDN: Intersection_Observer_API

// 기본구조는 콜백함수와 옵션
const io = new IntersectionObserver(callback, options);

callback

타겟 엘리먼트가 교차되었을 때 실행할 함수

option 객체

  • root
    • default: null, 브라우저의 viewport
    • 교차 영역의 기준이 될 root 엘리먼트. observe의 대상으로 등록할 엘리먼트는 반드시 root의 하위 엘리먼트

  • rootMargin

    • default: '0px 0px 0px 0px'
    • root 엘리먼트의 마진값. css에서 margin을 사용하는 방법으로 선언, 축약도 가능하다. px과 %로 표현가능
    • rootMargin 값에 따라 교차 영역이 확장 또는 축소


  • threshold

    • default: 0
    • 0.0부터 1.0 사이의 숫자 혹은 이 숫자들로 이루어진 배열로, 타겟 엘리먼트에 대한 교차 영역 비율을 의미
    • 0.0의 경우 타겟 엘리먼트가 교차영역에 진입했을 시점에 observer를 실행
    • 1.0의 경우 타켓 엘리먼트 전체가 교차영역에 들어왔을 때 observer를 실행




// 기본 예제

// options 설정
const options = {
  root: document.querySelector('.container'), 
  // .container class를 가진 엘리먼트를 root로 설정. null일 경우 브라우저 viewport
  rootMargin: '5px', // rootMargin을 '5px'로 설정
  threshold: [0, 0.5, 1] 
  // 타겟 엘리먼트가 교차영역에 진입, 교차영역에 타켓 엘리먼트의 50%가 있을 때, 
  //교차 영역에 타켓 엘리먼트의 100%가 있을 때 observe가 반응
}

// IntersectionObserver 생성
const io = new IntersectionObserver((entries, observer) => {
  // callback 함수
  // IntersectionObserverEntry 객체 리스트와 observer 본인을 받음
  entries.forEach(entry => {
    // entry와 observer 출력
    console.log('entry:', entry);
    console.log('observer:', observer);
  })
}, options)

참고 문헌

이미지 출처

profile
혼신의 힘을 다하다 🤷‍♂️

0개의 댓글