IntersectionObserver가 시야에 들어옵니다.

IntersectionObserver를 사용하면 관찰된 요소가 브라우저의 표시 영역에 진입하거나 종료될 때 이를 알 수 있습니다.

브라우저 지원

  • Chrome: 51.
  • Edge: 15.
  • Firefox: 55.
  • Safari: 12.1

소스

DOM의 요소가 표시되는 표시 영역에 진입하는 시점을 추적하려고 한다고 가정해 보겠습니다. 이미지를 적시에 지연 로드할 수 있도록 하거나 사용자가 실제로 특정 광고 배너를 보고 있는지 확인해야 할 수 있기 때문에 이렇게 할 수 있습니다. 스크롤 이벤트를 연결하거나 주기적 타이머를 사용하고 해당 요소에서 getBoundingClientRect()를 호출하면 됩니다.

하지만 이 접근 방식은 getBoundingClientRect()를 호출할 때마다 브라우저가 전체 페이지의 레이아웃을 다시 설정하게 하고 웹사이트에 상당한 버벅거림이 발생하기 때문에 속도가 매우 느립니다. 사이트가 iframe 내부에서 로드되고 있는 것을 알고 있고 사용자가 언제 요소를 볼 수 있는지 알고 싶다면 거의 불가능합니다. 단일 출처 모델과 브라우저를 사용하면 iframe이 포함된 웹페이지의 데이터에 액세스할 수 없습니다. 이는 iframe을 사용하여 자주 로드되는 광고에서 흔히 발생하는 문제입니다.

IntersectionObserver는 이 가시성 테스트를 더 효율적으로 만드는 것을 목적으로 설계되었으며 모든 최신 브라우저에 제공됩니다. IntersectionObserver를 사용하면 관찰된 요소가 브라우저의 표시 영역을 진입하거나 종료할 때 이를 알 수 있습니다.

iframe 공개 상태

IntersectionObserver를 만드는 방법

API는 다소 작으며 다음 예를 통해 가장 잘 설명되어 있습니다.

const io = new IntersectionObserver(entries => {
  console.log(entries);
}, {
  /* Using default options. Details below */
});

// Start observing an element
io.observe(element);

// Stop observing an element
// io.unobserve(element);

// Disable entire IntersectionObserver
// io.disconnect();

IntersectionObserver의 기본 옵션을 사용하면 요소가 부분적으로 표시될 때와 완전히 표시 영역을 벗어날 때 모두 콜백이 호출됩니다.

여러 요소를 관찰해야 하는 경우 observe()를 여러 번 호출하여 동일한 IntersectionObserver 인스턴스를 사용하는 여러 요소를 관찰하는 것이 좋습니다.

entries 매개변수는 IntersectionObserverEntry 객체 배열인 콜백에 전달됩니다. 이러한 각 객체에는 관찰된 요소 중 하나의 업데이트된 교차 데이터가 포함됩니다.

🔽[IntersectionObserverEntry]
    time: 3893.92
    🔽rootBounds: ClientRect
        bottom: 920
        height: 1024
        left: 0
        right: 1024
        top: 0
        width: 920
    🔽boundingClientRect: ClientRect
    // ...
    🔽intersectionRect: ClientRect
    // ...
    intersectionRatio: 0.54
    🔽target: div#observee
    // ...

rootBounds는 기본적으로 표시 영역인 루트 요소에서 getBoundingClientRect()를 호출한 결과입니다. boundingClientRect는 관찰된 요소에서 호출된 getBoundingClientRect()의 결과입니다. intersectionRect는 이 두 직사각형의 교차점으로, 관찰된 요소의 어떤 부분이 표시되는지 알려줍니다. intersectionRatio은 밀접한 관련이 있으며 요소가 얼마나 표시되는지 알려줍니다. 이제 이 정보를 활용하여 애셋이 화면에 표시되기 전에 애셋의 JIT 로드와 같은 기능을 구현할 수 있습니다. 효율적으로

교차 비율

IntersectionObserver는 데이터를 비동기식으로 전달하며 콜백 코드는 기본 스레드에서 실행됩니다. 또한 사양에 따르면 IntersectionObserver 구현은 requestIdleCallback()를 사용해야 합니다. 이는 제공된 콜백에 대한 호출의 우선순위가 낮으며 유휴 시간 동안 브라우저에서 실행함을 의미합니다. 이는 의도적인 디자인 결정입니다.

스크롤 div

요소 내에서 스크롤하는 것은 별로 좋아하지 않지만, 판단하는 것은 저나 IntersectionObserver의 일이 아닙니다. options 객체는 뷰포트의 대안을 루트로 정의할 수 있는 root 옵션을 사용합니다. root는 관찰된 모든 요소의 조상여야 한다는 점에 유의해야 합니다.

모든 것을 교차하세요.

아니요 나쁜 개발자! 이는 사용자의 CPU 사이클을 주의 깊게 사용하지 않는 것입니다. 무한 스크롤러를 예로 들어 보겠습니다. 이 시나리오에서는 DOM에 센티널을 추가하고 이를 관찰(및 재활용)하는 것이 좋습니다. 무한 스크롤러의 마지막 항목 가까이에 센티널을 추가해야 합니다. 이 감시자가 표시되면 콜백을 사용하여 데이터를 로드하고, 다음 항목을 만들고, DOM에 연결하고, 적절하게 감시자를 재배치할 수 있습니다. 센티널을 올바르게 재활용하면 observe()를 추가로 호출할 필요가 없습니다. IntersectionObserver는 계속 작동합니다.

무한 스크롤러

더 많은 업데이트가 필요합니다.

앞서 언급한 대로 콜백은 관찰된 요소가 부분적으로 표시될 때 한 번, 표시 영역을 벗어날 때 한 번 트리거됩니다. 이렇게 하면 IntersectionObserver을 통해 'X 요소가 뷰에 있나요?'라는 질문에 대한 답을 얻을 수 있습니다. 하지만 일부 사용 사례에서는 이 방법만으로는 충분하지 않을 수 있습니다.

이때 threshold 옵션이 유용합니다. 이를 통해 intersectionRatio 임곗값 배열을 정의할 수 있습니다. intersectionRatio가 이러한 값 중 하나를 교차할 때마다 콜백이 호출됩니다. threshold의 기본값은 [0]이며, 이는 기본 동작을 설명합니다. threshold[0, 0.25, 0.5, 0.75, 1]로 변경하면 요소의 4분의 1이 추가로 표시될 때마다 알림을 받습니다.

임계값 애니메이션

다른 옵션이 있나요?

현재 위에 나열된 옵션에 추가되는 옵션은 하나뿐입니다. rootMargin를 사용하면 루트의 여백을 지정할 수 있으므로 교차에 사용되는 영역을 효과적으로 늘리거나 줄일 수 있습니다. 이러한 여백은 "10px 20px 30px 40px"와 같이 CSS 스타일 문자열을 사용하여 지정되며 각각 상단, 오른쪽, 하단, 왼쪽 여백을 지정합니다. 요약하자면 IntersectionObserver 옵션 구조체는 다음 옵션을 제공합니다.

new IntersectionObserver(entries => {/* … */}, {
  // The root to use for intersection.
  // If not provided, use the top-level document's viewport.
  root: null,
  // Same as margin, can be 1, 2, 3 or 4 components, possibly negative lengths.
  // If an explicit root element is specified, components may be percentages of the
  // root element size.  If no explicit root element is specified, using a
  // percentage is an error.
  rootMargin: "0px",
  // Threshold(s) at which to trigger callback, specified as a ratio, or list of
  // ratios, of (visible area / total area) of the observed element (hence all
  // entries must be in the range [0, 1]).  Callback will be invoked when the
  // visible ratio of the observed element crosses a threshold in the list.
  threshold: [0],
});

<iframe> 매직

IntersectionObserver<iframe> 요소를 자주 사용하고 이러한 요소가 표시되는지 여부를 알면 유용할 수 있는 광고 서비스 및 소셜 네트워크 위젯을 염두에 두고 설계되었습니다. <iframe>가 요소 중 하나를 관찰하면 <iframe>를 스크롤할 때와 <iframe>가 포함된 창을 스크롤할 때 모두 적절한 시점에 콜백이 트리거됩니다. 그러나 후자의 경우 출처 간에 데이터가 유출되지 않도록 rootBoundsnull로 설정됩니다.

IntersectionObserver아닌 것은 무엇인가요?

명심해야 할 점은 IntersectionObserver는 의도적으로 픽셀이 완벽하거나 짧은 지연 시간이 아니라는 것입니다. 스크롤에 종속된 애니메이션과 같은 작업을 구현하는 데 이를 사용하면 실패할 수밖에 없습니다. 엄밀히 말해 데이터를 사용할 때는 데이터가 오래되었기 때문입니다. 설명서IntersectionObserver의 원래 사용 사례에 관한 자세한 내용이 포함되어 있습니다.

콜백에서 얼마나 많은 작업을 할 수 있나요?

간단히 요약: 콜백에서 너무 많은 시간을 소비하면 앱이 지연됩니다. 모든 일반적인 관행이 적용됩니다.

요소를 교차하세요.

IntersectionObserver모든 최신 브라우저에서 사용할 수 있으므로 브라우저 지원이 우수합니다. 필요한 경우 이전 브라우저에서 폴리필을 사용할 수 있으며 WICG 저장소에서 사용할 수 있습니다. 물론 이 폴리필을 사용하면 네이티브 구현에서 얻을 수 있는 성능 이점을 얻을 수 없습니다.

지금 바로 IntersectionObserver을(를) 사용할 수 있습니다. 생각해낸 내용을 알려주세요.