노트

이미지 loading 속성

Lazy Loading

프런트엔드#html#performance · 연결된 개념 6개

쉽게 말하면

이미지 loading 속성을 lazy로 두면 화면 밖 이미지는 스크롤해서 가까워질 때까지 받지 않아요. 수도꼭지 하나로 물을 받을 때 지금 쓸 그릇부터 채우는 셈이라 중요한 파일이 먼저 도착해요.

비유가 깨지는 곳 그렇다고 다 lazy로 두면 안 돼요. 첫 화면의 주인공 이미지(LCP 후보)에 걸면 다운로드가 늦게 시작돼 LCP가 나빠지고, width·height가 없으면 늦게 온 이미지가 레이아웃을 밀어요.

img·iframe의 loading 속성으로 리소스를 언제 내려받을지 정한다. eager(기본)는 태그를 만나자마자, lazy는 화면에 가까워질 때까지 미룬다. JS(JavaScript) 없이 동작하는 브라우저 기본 기능이라 IntersectionObserver로 직접 만들 필요가 없다.

  • lazy의 "가까움" 기준은 브라우저가 정한다(Chrome은 네트워크 속도에 따라 수백~수천 px 여유를 둔다)
  • 화면 밖 이미지는 아예 받지 않으므로 처음 내려받는 바이트와 요청 수가 크게 준다

진짜 효과: 중요한 것을 먼저 받게 하기

이미지는 CSS나 동기 스크립트와 달리 렌더링을 막지 않는다. 다 받지 못해도 페이지는 그려지고 자리만 비어 있다. 그런데도 eager 이미지가 많으면 간접적으로 느려진다.

  • 대역폭 경쟁: 수십 장이 동시에 받아지면 CSS·폰트·JS·LCP(Largest Contentful Paint) 이미지와 대역폭을 나눠 쓴다. HTTP/2여도 파이프는 하나다
  • 디코드: 받은 이미지는 압축을 풀어야 그려진다. 큰 이미지 여럿을 동시에 풀면 스크롤이 버벅일 수 있다(decoding="async"로 완화)
  • 메모리: 풀린 비트맵이 RAM(Random Access Memory)을 차지해 저사양 기기에 부담이다

브라우저도 화면 밖 eager 이미지의 우선순위를 낮추긴 하지만, 결국 전부 받고 큐를 차지한다. 그리드 상품 이미지에 lazy를 걸면 이미지 바이트뿐 아니라 LCP도 좋아지는 이유가 이 경쟁이 풀려서다.

주의

  • 첫 화면의 주인공 이미지(LCP 후보)에는 lazy를 쓰지 않는다. 다운로드가 늦게 시작돼 LCP가 나빠진다. 오히려 우선순위를 올린다 → 이미지 로딩 우선순위(loading·fetchpriority), preload
  • width·height(또는 aspect-ratio)를 꼭 준다. 늦게 들어오는 이미지가 레이아웃을 밀면 CLS(Cumulative Layout Shift)가 나빠진다
  • display: none으로 숨긴 lazy 이미지는 Chrome·Safari·Firefox 모두 받지 않는다. 반면 opacity: 0처럼 다른 방식으로 숨기면 받는다
  • Next.js Image는 기본이 lazy이고, 우선 로드 옵션을 주면 eager + preload로 바뀐다. 옵션 이름은 버전에 따라 다르다 → Next.js 16 변경점

출처: MDN — Lazy loading: Loading attribute · web.dev — Browser-level image lazy loading for the web

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • loading 경계와 레이아웃 끌어올리기

    Next.js App Router에서 loading.tsx는 같은 세그먼트의 page와 그 아래(하위 layout 포함)를 suspense로 감싸지만, **같은 세그먼트의 layout은 감싸지 않는다**. 그래서 데이터를 기다릴 필요가 없는 공통 UI(탭바, 필터 헤더)를 page에서 layout으로 끌어올리면 스켈레톤에 덮이지 않고 처음부터 실제 모습으로 보인다.

  • 브라우저 렌더링 파이프라인

    브라우저가 받은 HTML·CSS·JS를 화면의 픽셀로 바꾸는 순서. 처음 로드할 때도, 이후 무언가 바뀔 때도 같은 단계를 거친다. 바뀐 내용에 따라 어느 단계부터 다시 시작하는지만 다르다.

  • 브라우저 캐시

    한 번 받은 리소스(HTML·CSS·JS·이미지)를 브라우저가 저장해 두었다가 다시 쓰는 기능. 서버가 응답 헤더로 얼마나, 어떻게 캐시할지 알려 주고 브라우저가 그대로 따른다.

  • SEO

    SEO(Search Engine Optimization)는 검색 엔진이 페이지를 잘 찾고(크롤링, crawling), 이해해서 저장하고(색인, indexing), 알맞은 검색어로 노출하도록(순위, ranking) 사이트를 다듬는 일이다. 개발자가 맡는 부분은 대부분 앞의 두 단계, 즉 "검색 엔진이 읽을 수 있게 만드는 것"이다.

  • 리플로우(레이아웃 재계산)

    요소의 크기나 위치가 바뀌어 브라우저가 레이아웃을 다시 계산하는 일. 렌더링 파이프라인에서 대개 가장 비싼 단계이고, 리플로우가 일어나면 뒤따라 페인트와 합성도 다시 한다.

보기 옵션