WEB/REACT

[REACT] React swiper에 image lazy loading 적용하기/ intersection observer

자바칩 프라푸치노 2021. 9. 8. 12:12

오늘의 과제

페이지 로딩 속도를 빠르게 만들어보자!

 

이 페이지의 로딩 속도를 빠르게 만들고 싶다.

 

 

 

 

지금 FINISH부분을 보면 무려 거의 28초나 걸린다. 물론 3G 환경에서.

 

왜그렇나 보니. 지금 컬렉션들이 눈에는 6개밖에 이미지가 안보이지만,

전체 이미지가 다 불러와지기 때문에 속도가 느린것이다.

그러면 이미지에 LAZY LOADING을 적용해야한다.

 

 

 


 

 

Lazy Loading 이란?

쉽게 말해서 눈에 보이는 이미지만 불러온다는 것이다.

그러니까 미리 이미지를 다 불러오지 말고, 스와이프를 넘겨서 옆의 이미지가 나왔을때,

이미지를 불러오는 것이다.

 

출처: https://blog.chromium.org/2019/10/automatically-lazy-loading-offscreen.html

 

 

 

 


 

라이브러리의 lazy loading적용하기

 

먼저, 나는 react swiper라는 라이브러리를 사용해 저 스와이퍼를 구현하고 있었기 때문에

swiper을 적용한 사람들이 lazy loading을 어떻게 적용하는지 찾아보았다.

https://swiperjs.com/react

여기에 보면 lazy loading 관련 코드가 있긴 있는데,,,

도무지 어떻게 적용하는지 모르겠는거다......... 적용도 안되고

swiper을 쓰면서 lazy loading을 적용한 사람이 없는가. 관련 블로그 글도 없었다..........

 

그래서 나는 일단 다른 라이브러리를 찾아서 적용을 해봤지만

finish가 38초가 됐다.. ㅋㅋㅋㅋㅋ

라이브러리에서 또 모듈을 가져와써서 그런건지,, lazy loading을 적용하지 않을때는 28초, 적용하니 38초

이것은 뭔가 잘못됐다.

 

 

 


 

 

Intersection observer 이용하기

팀원분의 도움으로 Intersection observer을 이용하여 lazy loading을 적용했다.

 

Intersection Observer란?

 

 

 

How?

 

 

 

요 카드 하나하나에 intersection observer를 붙이는 거다.

이것은 Collection이라는 하나의 컴포넌트였다.

 

저 사진이 보여지는 img태그에

const observeImage = useRef(null)

이렇게 ref를 주었다.

 

  <Image
        data-src={props.image} 
        ref={observeImage}
        />

 

data-src라는 것은 data set이라는 객체에 src라는 이름으로 props.image 값이 들어가는 것이다.

ref로 아까 설정해준 observeImage를 주었다.

 

 

 useEffect(() => {
        const observer = new IntersectionObserver(showImage, {threshold: 0.1}); //메인이미지 관찰
        observer.observe(observeImage.current)
      return () => {
        observer.disconnect();}
      },[])

 

useEffect에서는 observer객체를 만들어준다.

첫번째 파라미터에는 이 함수가 감지되면 어떤 함수를 실행할 것인지를 넣고

두번째 인자로 threshold라는 것은 이 이미지가 화면에 몇 퍼센트 나왔냐를 감지하는 것이다.

0.1이라는 것은 10퍼센트만 보이면 showImage함수가 실행되는 것이다.

 

 

 

 const showImage = async([entry], observer) => {
    if (!entry.isIntersecting) {
      return
    }
    const imageUrl = [entry][0].target.dataset.src //보여진 리뷰의 인덱스
    observeImage.current.src = imageUrl
    observer.unobserve(entry.target) // 함수가 실행될 때, 관찰을 끝내기.
}

 

 

showImage함수에서 보면 const imageUrl부터 보면된다.

imageUrl에 아까 data-src로 넣었던 값을 넣어주는 것이다.

그리고 ref로 잡은 observeImage의 current.src를 그 imageUrl로 넣는다.

 

그러면 처음에는 화면에서

4개의 온전한 이미지와 2개의 짤린 이미지가 보이겠다.

그리고 스와이프를 넘기면 해당 이미지만 로딩이 되는 것이다.

 

 

결과적으로 28초 -> 14초가 되었다.

 

 

 

728x90