카테고리 없음

인터섹션 옵저버(Intersection Observer) - 뷰포트

lamarcK 2025. 3. 25. 00:43

인터섹션 옵저버(Intersection Observer)는 웹 페이지에서 특정 요소가 뷰포트(viewport) 또는 지정된 부모 요소와 교차하는 시점을 감지하는 웹 API이다.

스크롤 이벤트나 타이머를 사용하여 요소의 가시성을 확인하는 기존 방식보다 효율적이고 성능이 뛰어나며, 다양한 상황에서 유용하게 활용된다.

 

인터섹션 옵저버의 주요 특징 및 장점

1. 비동기적 처리

  • 인터섹션 옵저버는 메인 스레드와 독립적으로 비동기적으로 작동하므로, 페이지 성능에 미치는 영향이 적다.
  • 이는 스크롤 이벤트와 같이 동기적으로 작동하는 방식보다 훨씬 효율적이다.

브라우저에 실행 위임

인터섹션 옵저버는 브라우저에게 실행을 넘겼기 때문에 비동기적으로 코드가 실행된다. 즉 가시성 부분을 브라우저가 처리하여 순서에 상관없이 코드를 처리할 수 있는 것이다.

스크롤 이벤트

웹 페이지에서 사용자가 스크롤바를 움직이거나 마우스 휠, 터치 등을 통해 페이지를 스크롤할 때 발생하는 이벤트

  • 해당 이벤트 발생 - 코드 실행 방식이기 때문에 동기적이다.

2. 성능 최적화

  • 브라우저가 최적화를 수행하여 불필요한 연산을 줄여준다.
  • 이는 스크롤 이벤트나 타이머를 사용하는 방식보다 성능이 뛰어나다.

메모리의 효율적 사용

인터섹션 옵저버는 특정 상황에서만 이벤트를 발생하게 할 수 있어서 굳이 모든 이벤트를 메모리에 등록하고 대기하고 있을 이유가 없다.

일반적인 이벤트의 작동 방식을 사용한다면 클릭, 스크롤 같은 모든 이벤트가 발생했을 때마다 이벤트 리스너에 이벤트를 전달해야 하기 때문에 메모리를 더 많이 사용하게 된다.

3. 유연한 설정

  • 교차 영역의 비율, 루트 요소, 마진 등 다양한 옵션을 설정하여 원하는 시점에 콜백 함수를 실행할 수 있다.

뷰 포인트를 기준으로 이벤트의 발생 조건을 설정가능

인터섹션 옵저버는 뷰 포인트를 기준으로 화면의 모양 등을 수정가능하고, 필요한 시점에 코드를 실행 시키는 것이 가능하다.

4. 다양한 활용

  • 이미지 지연 로딩 (lazy loading), 무한 스크롤, 광고 노출 측정, 요소의 애니메이션 효과 등 다양한 용도로 활용할 수 있다.

인터섹션 옵저버의 사용 방법

  1. 옵저버 생성:
    • IntersectionObserver 생성자를 사용하여 옵저버를 생성합니다.
    • 생성자는 콜백 함수와 옵션 객체를 인자로 받습니다.
  2. 관찰 대상 등록:
    • observe() 메서드를 사용하여 관찰할 대상 요소를 등록합니다.
  3. 콜백 함수 실행:
    • 관찰 대상 요소가 설정된 조건에 따라 교차하면 콜백 함수가 실행됩니다.
    • 콜백함수는 intersection객체들을 배열로 받습니다. 각 intersection객체는 관찰 대상 요소의 교차 정보를 담고 있습니다.
  4. 관찰 해제:
    • 관찰이 더이상 필요하지 않다면, unobserve() 메서드를 사용하여 관찰 대상 요소를 해제하거나, disconnect() 메서드를 사용하여 옵저버 자체를 해제할수 있습니다.

인터섹션 옵저버의 활용 예시

  • 이미지 지연 로딩:
    • 사용자가 이미지가 뷰포트에 나타날 때 이미지를 로드하여 초기 페이지 로딩 속도를 향상시킬 수 있습니다.
  • 무한 스크롤:
    • 사용자가 페이지 하단에 도달할 때 추가 콘텐츠를 로드하여 끊김 없는 사용자 경험을 제공할 수 있습니다.
  • 광고 노출 측정:
    • 광고가 뷰포트에 노출된 시간을 측정하여 광고 효과를 분석할 수 있습니다.

1. 이미지 지연 로딩 (Lazy Loading) 예시:

HTML (index.html):

<!DOCTYPE html>
<html>
<head>
    <title>Intersection Observer - Lazy Loading</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="lazy-load">
        <img data-src="https://placehold.co/500x300?text=Image+1" alt="Lazy Load Image 1">
    </div>
    <div class="lazy-load">
        <img data-src="https://placehold.co/500x300?text=Image+2" alt="Lazy Load Image 2">
    </div>
    <div class="lazy-load">
        <img data-src="https://placehold.co/500x300?text=Image+3" alt="Lazy Load Image 3">
    </div>
    <script src="script.js"></script>
</body>
</html>

CSS (style.css):

.lazy-load {
    width: 500px;
    height: 300px;
    background-color: lightgray;
    margin-bottom: 20px;
}

.lazy-load img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

JavaScript (script.js):

const lazyImages = document.querySelectorAll('.lazy-load img'); // 수정된 부분

const observer = new IntersectionObserver((entries, observer) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      console.log(img.dataset.src);
      observer.unobserve(img);
    }
  });
});

lazyImages.forEach((image) => {
  observer.observe(image);
});

2. 무한 스크롤 (Infinite Scroll) 예시:

HTML (index.html):

<!DOCTYPE html>
<html>
<head>
    <title>Intersection Observer - Infinite Scroll</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="content-container">
        <p>콘텐츠 1</p>
        <p>콘텐츠 2</p>
        <p>콘텐츠 3</p>
        <div id="sentinel"></div>
    </div>
    <script src="script.js"></script>
</body>
</html>

css (style.css):

#content-container {
    height: 200px;
    overflow-y: auto;
}

JavaScript (script.js):

const sentinel = document.querySelector('#sentinel');

const observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
        if (entry.isIntersecting) {
            loadMoreContent();
        }
    });
});

observer.observe(sentinel);

function loadMoreContent() {
    const newContent = document.createElement('p');
    newContent.textContent = '추가 콘텐츠';
    document.querySelector('#content-container').appendChild(newContent);
}

이처럼 HTML, CSS, JavaScript 코드를 분리하여 구성하면 코드의 가독성과 유지보수성을 높일 수 있습니다. HTML은 웹 페이지의 구조를 정의하고, CSS는 스타일을 정의하며, JavaScript는 동적인 기능을 구현합니다.