Please enable JavaScript to view the comments powered by Disqus.

Intersection Observer API와 lozad.js 로 이미지 지연 로딩하기

이미지가 많은 웹사이트에서는 브라우저 화면상에 표시되지 않은 영역의 이미지의 로딩을 의도적으로 지연시켜서 네트워크 트래픽과 성능에 도움을 주는 방법을 많이 사용한다.

그런데 지연 로딩(lazy loading)이라고 불리는 이 기법을 구현하는 전통적인 방식에는 문제가 있다. 브라우저 스크롤 이벤트에 리스너를 붙여서 현재 스크롤의 위치와 getBoundingClientRect같은 API를 사용해서 얻은 엘레멘트의 위칫값을 주기적으로 비교해야 하기 때문이다.

최근 브라우저에 추가된 API인 Intersection Observer API를 사용하면 이처럼 리소스 소모가 많은 방식을 대체할 수 있다.

Intersection Observer API

Intersection Observer API는 이름 그대로 브라우저 뷰포트와 엘레멘트의 교차점(intersection)과 관련된 기능이다. 뷰포트에 엘레멘트가 표시되면 옵저버는 이벤트를 발생시키기 때문에 개발자는 콜백 함수에서 원하는 작업을 수행할 수 있다.

사용법은 그렇게 복잡하지 않다. 옵션과 함께 옵저버 인스턴스를 생성하고 탐지할 엘레멘트를 지정하면 된다. 상세한 사용법은 MDN의 API 문서를 살펴보면 알 수 있다.

const options = {
  root: document.querySelector('#scrollArea'), // null은 브라우저 전체 영역
  rootMargin: '10% 10px', // 요소가 감지되는 영역을 추가하거나 줄일 수 있다. CSS margin 같은 속성에 사용하는 축약형처럼 작성할 수 있다.
  threshold: 0, // 콜백을 실행시킬 지점. 0은 보이자마자, 1은 모두 표시된 후
}

const callback = (entries, observer) => {
  entries.forEach(entry => {
    // entry는 탐지된 엘레멘트의 정보를 가지고 있다.
    // ex)
    //    entry.isIntersecting,
    //    entry.boundingClientRect
  })
}

const observer = new IntersectionObserver(callback, options); // 옵저버 인스턴스 생성

const target = document.querySelector('#listItem'); // 탐지할 엘레멘트

observer.observe(target);

lozad.js로 간단하게 Intersection API 사용하기

lozad.js는 이미지 지연 로딩에 특화된 Intersection API 구현 사례라고 할 수 있다. 복잡한 설정 필요 없이 이미지 태그에 라이브러리가 요구하는 속성을 추가한 후 옵저버 인스턴스를 생성하면 이미지 지연 로딩이 간단히 구현된다.

image 태그에는 src 속성 대신 data-src에 이미지의 경로를 할당하고 lozad라는 이름의 클래스 이름을 추가해야 한다. (클래스명은 인스턴스 옵션으로 바꿀 수 있다)

<img class="lozad" data-src="image.png" />
const observer = lozad(); // 옵션을 지정하지 않으면 lozad라는 클래스가 붙은 이미지 태그를 지연 로딩한다.
observer.observe();

이것이 전부다. lozad.js는 앞서 설명한 Intersection Observer를 사용하는 과정에서 타겟 요소를 설정하고 이미지 불러오는 로직을 자동으로 처리해주기에 지연 로딩을 무척 간단히 구현할 수 있다. 물론 Intersection API에서 제공하는 rootMargin, threshold, 콜백 함수도 사용할 수 있다.

예제

lozad.js를 사용해 간단히 만들어 본 예제 페이지에서는 이미지가 로드된 후 콜백 함수에서 페이드인 효과를 추가하고, 토스트 메시지를 표시하도록 했다.

https://rhostem.github.io/lozad-example

polyfill 설치

caniuse-intersection-api http://caniuse.com/#feat=intersectionobserver

2017년 10월 현재 크롬 최신 버전에서는 사용할 수 있지만 사파리 브라우저는 데스크탑, 모바일 모두 지원하지 않는다. 많은 웹 브라우저가 지원하지 않기 때문에 polyfill 설치가 필수적이다.

polyfill 설치를 위해서는 스크립트 직접 추가하거나, NPM 모듈을 설치한 후 추가하는 방법이 있다.

<!-- 메인 스크립트보다 먼저 불러와야 한다. -->
<script src="path/to/intersection-observer.js"></script>
// 가능하면 entry 파일에서 다른 모듈보다 먼저 불러와야 한다.
require('intersection-observer');

참조