IntersectionObserver를 활용한 Lazy Loading

김학재·2021년 2월 16일
0

프론트엔드

목록 보기
6/12

lazy loading

문제점

react를 활용해 웹사이트를 구축해 github page에 배포하는 프로젝트를 진행 중에 있다.
서브웨이의 사용법 및 재료들을 소개하는 웹사이트인데 한 페이지에 많게는 10개가 넘는 이미지를 표시하다보니 네트워크 상황에 따라 다른 DOM 요소들은 렌더링이 완료되었음에도 이미지가 로딩되지 않아 볼 수 없는 경우가 종종 발생했다.
이를 해결하기 위해 Lazy-Loading을 적용하기로 했고 결과적으로는 IntersectionObserver를 활용했다.
적용 과정에서 배운 내용 및 발생한 문제점을 정리하기로 했다.


Lazy Loading이란?

mozilla - Lazy Loading
직역하면 게으른 로딩이다. 웹 페이지가 열리면 페이지 내의 모든 요소들을 화면에 한번에 로딩하는 것이 아닌 실제로 화면에 나타날 때 로딩하는 기술이다.
lazy loading gif
위 이미지는 쇼피파이에서 lazy loading을 적용한 예시이다. 한 번에 여러 개의 이미지를 로딩하는 대신 blur 처리된 이미지를 먼저 보여주고 화면에 나타날 때 로딩을 하거나, 시계 바늘이 돌아가는 loading 사진을 먼저 보여주는 방식으로 적용이 가능하다.

장점

1. 성능 향상
페이지 초기 로딩 시 필요한 요소들의 수를 줄임으로써 불필요한 다운로드를 방지할 수 있다. 결과적으로 다른 리소스들의 다운로드를 더 빠르게 처리하도록 할 수 있다.
2. 비용 감소
1번과 상통하는 부분이다. 또한, 페이지를 끝까지 스크롤하지 않거나 상단 부분만 사용하는 유저에게도 최적화된 웹 사이트를 제공할 수 있다.

IntersectionObserver

scroll 이벤트 리스너를 사용하거나 native lazy loading을 사용하는 기존의 방법들도 있지만 나는 IntersectionObserver를 활용하기로 했다.

scroll 이벤트 리스너를 사용하는 경우
수많은 이벤트가 발생함에 따라 수많은 reflow가 발생하게 된다. 이를 해결하기 위해 throttle, debounce 의 사용이 필요하다.

native lazy loading을 사용하는 경우

<img src="image.png" loading="lazy" alt="" width="200" height="200">

이미지의 loading 속성에 lazy를 지정할 수 있지만 아직 최신 브라우저에서만 사용이 가능하다.
lazy loading support - canIUse

IntersectionObserver는 2016년 처음 소개되었으며 mozilla에서는 그 활용방안을 다음과 같이 소개하고 있다.

  • 페이지가 스크롤 되는 도중에 발생하는 이미지나 다른 컨텐츠의 지연 로딩.
  • 스크롤 시에, 더 많은 컨텐츠가 로드 및 렌더링되어 사용자가 페이지를 이동하지 않아도 되게 하는 infinite-scroll 을 구현.
  • 광고 수익을 계산하기 위한 용도로 광고의 가시성 보고.
  • 사용자에게 결과가 표시되는 여부에 따라 작업이나 애니메이션을 수행할 지 여부를 결정.

사용

// IntersectionObserver 를 등록한다.
const io = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    // Each entry describes an intersection change for one observed
    // target element:
    //   entry.boundingClientRect
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
  })
})

// 관찰할 대상을 선언하고, 해당 속성을 관찰시킨다.
// 이미지의 경우 다음과 같이 사용 가능
const images = document.querySelectorAll('img');
images.forEach((image) => {
  io.observe(image);
})

내용을 정리하다 보니 IntersectionObserver 관련 내용이 너무 길어진 것 같아 실제 웹 사이트에 적용 예시 및 해결 과정은 다음 글에 정리해야겠다.

profile
YOU ARE BREATHTAKING

0개의 댓글