Work/JacaScript

lazy loading

디쟈이너 2021. 11. 5. 19:57

Lazy loading이란?

페이지 내에 바로 필요하지 않은 이미지들의 로딩 시점을 뒤로 미룬다.

  1. 성능 향상

    페이지 초기 로딩 시 필요한 이미지의 수를 줄일 수 있다. 리소스 요청을 줄이는것은 다운로드 bytes를 줄이는 것이다.

  2. 비용 감소

    이미지가 보여지지 않으면 절대 로딩하지 않으므로, 페이지 내에서 전달할 총 바이트 용량을 줄일 수 있다.

기술

  1. 태그를 이용한 일반적인 방법
    • 이미지 로딩을 사전에 막는다.
    • <img> 태그를 사용하는 경우, 이미지를 가져올 때 src 속성을 사용하는데, HTML은 무조건 모든 이미지의 src를 로드한다.
    • 이를 막기 위해 src 가 아닌 data-src 에 이미지 URL을 지정한다.
    • 그리고 이미지가 뷰포트에 들어오자마자 로딩할 수 있도록 브라우저에게 알려준다.
  2. 자바 스크립트 이벤트로 image load 하기
    • 브라우저 내 scroll, resize, orientationChange 이벤트 리스너를 이용할 수 있다.
    • scroll 이벤트는 사용자가 페이지에서 스크롤하는 시점을 확인한다.
    • resize는 브라우저의 크기가 바뀔때 발생한다.
    • orientationChange는 디바이스 화면이 가로에서 세로(혹은 반대로) 바뀔때 발생한다.
    • 아직 로딩되지 않은 이미지를 모두 찾고, 윈도우 높이, 스크롤 위치, 이미지의 위치를 이용해 어떤 이미지가 뷰포트 안에 있는지 확인한다.
    • 뷰포트 안에 들어가면 <img> 태그의 <data-src> 속성에 지정된 URL을 <src> 속성에 넣어 이미지를 로드한다.
    • 이후, 나중에 트리거 이벤트를 위해 로딩을 지연시킬 이미지로 식별하던 lazy class 를 제거한다. 모든 이미지가 로딩되면 트리거를 일으키던 이벤트 리스너를 제거한다.
  3. Intersection Observer API를 이용하여 image load 하기
    • 모든 이미지에 옵저버를 부착한다.
    • 엘리먼트가 뷰포트에 들어왔을 때, API가 감지하고 isIntersecting 속성을 이용해 URL을 data-src 에서 src 속서응로 이동시킨다. 전부 로드되면 lazy class 를 제거하고 옵저버도 제거한다.
  4. Native Lazy Loading
    • 최신 Google Chrom 브라우저 (Chrmone 76) 에서 지원하는 기능
    • <img> 태그에 loading 속성만 추가하면 된다
    • loading 속성에 사용할 수 있는 값
      • lazy - 뷰포트에서 일정한 거리에 닿을 때까지 로딩을 지연시킵니다.
      • eager - 현재 페이지 위치가 위, 아래 어디에 위치하던 상관없이, 페이지가 로딩되자마자 해당 요소를 로딩합니다.
      • auto - 이 속성은 디폴트로 로딩을 지연하는 것을 트리거합니다. 기본적으로 이것은 loading 속성을 쓰지 않을 것과 같습니다.
    • 반드시 heightwidth 를 인라인으로 추가해야한다
  5. CSS로 불러온 Background image를 Lazy Loading 하기
    • CSS background image를 로드하기 위해서는 현재 문서내 DOM 노드에 CSS 스타일이 적용되는지 여부를 결정하기 위해 CSSOM(CSS Object Model)과 DOM(Document Object Model) Tree를 구성해야한다.
    • 구현 방식은 위와 똑같다. 엘리먼트가 뷰포트에 들어올때 까지 CSS background image 속성을 적용하지 않는다.
    • 이 때, CSS는 아래와 같은 처리가 필요하다
      • lazy 클래스 추가시 background-image: none 처리
      • 엘리먼트가 뷰포트에 들어오면 lazy 클래스 제거

사용성 향상하기

  1. 올바른 image placeholder 사용하기
    • 단색 이미지(회색 등) 사용하기
    • 이미지에 사용하는 주요 색상 사용하기
      • 이미지의 첫 1x1 픽셀로 스케일을 감소시키고, 해당 픽셀 요소로 placeholder를 채움
      • ImageKit을 사ㅛㅇ해 주요 단일 색상을 얻을 수 있음
    • 저화질 이미지로 대체하기
      • 주요 색상보다 더 좋은 방식이다
      • 원본 이미지의 저화질 흐린 이미지를 사용함으로써 원본 이미지에 대해 어느정도 추측하도록 유도할 수 있다.
  2. 이미지 로딩을 위한 버퍼 시간 추가하기
    • 이미지가 뷰포트에 들어왔을 때 이미지가 로딩되는 경우. 스크롤을 많이 했을때 사용자의 대기시간이 급격히 늘어날 수 있다. 이는 사용성에 좋지 않다
    • 이미지의 로딩 트리거 시점에 마진값을 넣는다.즉, 뷰포트보다 500px 정도 아래에서 로딩을 하는것이다.
  3. Lazy loading으로 인해 레이아웃이 깨지는 문제 방지하기
    • 문제점: 이미지가 없을 때, CSS로 따로 지정해주지 않으면 콘텐트를 감싼 컨테이너는 공간을 따로 가지지 않아 0x0 픽셀로 공간이 없다가 이지가 추가되면 컨테이너를 리사이징 한다.
    • 해결 방법: 컨테이너에 너비/높이를 지정해 문제를 피할 수 있다.

lazy loading 테스트 방법

  • 크롬 브라우저 개발자 도구 > 내 네트워크 > 이미지 확인
  • 스크롤을 아래로 내릴 때 이미지가 로딩된다

Skeleton UI

(더 찾아보고 싶은고..)

참고 자료

반응형