• 티스토리 홈
  • 프로필사진
    홍유진
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
홍유진
  • 프로필사진
    홍유진
    • 분류 전체보기 (22)
      • Coding Test (0)
      • Web Frontend (19)
        • Problem Solving (0)
        • HTML_CSS (10)
      • Workflow (1)
      • Database (1)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • IntersectionObserver를 활용한 Lazy Loading 적용
        2024년 06월 23일
        • 홍유진
        • 작성자
        • 2024.06.23.:34

        문제

        앞서 웹 성능 최적화 파트에 이어서 웹툰 목록을 조회하는 기능을 구현하던 중 많은 데이터 목록을 한 번에 불러와 렌더링 속도가 느려지는 현상이 있었다.

         

        해결 전

        영상에서 보면 한번에 이미지가 많이 불러와 지는 것을 볼 수 있다.

        이를 해결하기 위해서 초기 화면에 보여지는 만큼의 목록만 불러오고, 사용자가 스크롤을 내릴 때 추가 이미지를 불러오는 방식을 적용했다. 이 과정에서 IntersectionObserver를 사용한 Lazy Loading을 도입하여 성능을 최적화 할 수 있었다.

         

        IntersectionObserver이란?

        요소가 뷰포트(Viewport) 내에서 보이는지 여부를 비동기적으로 관찰할 수 있는 API이다. 스크롤 이벤트를 직접 다루지 않고도 특정 요소가 화면에 들어오거나 나가는 시점을 쉽게 감지할 수 있다. 

         

        해결

        const observer = useRef();
        
        const handleLazyLoad = (entries, observer) => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              const img = entry.target;
              img.src = img.dataset.src; // data-src 속성에 저장된 실제 이미지 URL을 img 태그의 src 속성으로 설정
              observer.unobserve(img); // 이미지가 로드되면 더 이상 관찰하지 않도록 설정
            }
          });
        };
        
        useEffect(() => {
          observer.current = new IntersectionObserver(handleLazyLoad); // IntersectionObserver 생성
          const images = document.querySelectorAll('img[data-src]'); // data-src 속성을 가진 모든 img 태그를 선택
          images.forEach(img => observer.current.observe(img)); // 각 img 태그를 관찰 대상으로 설정
        
          return () => {
            if (observer.current) {
              observer.current.disconnect(); // 컴포넌트가 언마운트될 때 관찰을 중단
            }
          };
        }, [webtoons]); // webtoons가 변경될 때마다 새로 설정
          <Image
            data-src={webtoon.thumbnail[0]}
            alt="웹툰 이미지"
            loading="lazy"
         />
        1. IntersectionObserver 생성
          • handleLazyLoad 함수는 요소가 뷰포트에 진입하거나 나갈 때 호출된다.
        2. handleLazyLoad 함수
          • entries 배열을 순회하며 각 entry가 뷰토프에 진입했는지 (entry,isInterseting)를 확인한다.
          • 만약 요소가 진입했다면 data-src 속성에 저장된 실제 이미지 URL을 src 속성으로 설정하여 이미지를 로드한다.
          • 이미지가 로드되면 해당 요소를 더 이상 관찰하지 않도록 observer.unobserve(img)를 호출한다.
        3. useEffect 훅
          1. useEffect 훅 내에서 IntersectionObserver를 생성하고, data-src 속성을 가진 모든 img 태그를 관찰 대상으로 설정한다.
          2. 컴포넌트가 언마운트될 때 observer.current.disconnect()를 호출하여 관찰을 중단한다.
          3. webtoons가 변경될 때마다 새로 설정한다.

         

        결과

        결과

        네트워크 탭을 보면 처음에는 화면에 보이는 이미지만 불러오고 스크롤하면서 이미지가 더 생기는 것을 볼 수 있다.

        'Web Frontend' 카테고리의 다른 글

        Recoil 새로고침 랜더링 문제  (0) 2024.08.03
        react-Intersection-Observer 라이브러리를 이용해 무한스크롤 구현하기  (0) 2024.08.02
        ThemeProvider로 theme.ts에서 디자인 시스템 설정하기  (0) 2024.07.10
        Promise.all을 활용한 페이지네이션 해결  (0) 2024.06.22
        웹 성능 최적화: 이미지 및 폰트 최적화  (0) 2024.06.07
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바