본문 바로가기
Frontend2026년 8월 20일5분 읽기

ResizeObserver — 요소 크기 변화를 감지하는 실전 패턴

YS
김영삼
조회 8
ResizeObserver — 요소 크기 변화를 감지하는 실전 패턴

ResizeObserver는 특정 요소의 크기가 바뀌는 순간을 감지하는 브라우저 API입니다. 창 전체가 아니라 개별 요소의 가로·세로 변화를 콜백으로 알려주죠. 사이드바가 접혀 콘텐츠 폭이 줄거나, 부모 컨테이너가 리사이즈될 때처럼 window.resize로는 못 잡는 변화를 잡아냅니다.

예전엔 이런 걸 window.resize에 물려 폴링하듯 처리했는데, 요소 자체가 커진 건 창 크기가 그대로면 이벤트가 안 옵니다. 그때마다 억지로 리사이즈 이벤트를 흉내 내다 성능을 깎아먹곤 했죠.

기본 사용법

const ro = new ResizeObserver((entries) => {
  for (const entry of entries) {
    const { width, height } = entry.contentRect;
    console.log('새 크기', width, height);
  }
});
ro.observe(document.querySelector('.panel'));
// 그만 볼 땐: ro.unobserve(el) 또는 ro.disconnect()

콜백은 관찰 중인 요소가 리사이즈될 때마다 호출되고, entries에 어떤 요소가 어떻게 바뀌었는지 담겨 옵니다. 하나의 옵저버로 여러 요소를 동시에 감시할 수 있어요.

contentRect보다 정확한 box 속성

contentRect도 되지만, 요즘은 borderBoxSize·contentBoxSize를 권장합니다. 패딩·보더 포함 여부를 명확히 고를 수 있고 값도 더 정확합니다.

속성포함 범위
contentBoxSize콘텐츠 영역만
borderBoxSize패딩·보더 포함
devicePixelContentBoxSize실제 디바이스 픽셀(캔버스용)
const ro = new ResizeObserver(([entry]) => {
  const w = entry.borderBoxSize[0].inlineSize;
  el.classList.toggle('narrow', w < 400);
});

참고로 borderBoxSize는 배열입니다. 멀티컬럼 같은 조각난 레이아웃 대비라 보통은 [0]을 쓰고, inlineSize(가로)·blockSize(세로)로 읽습니다.

악명 높은 루프 에러

ResizeObserver loop completed with undelivered notifications — 이 경고, 한 번쯤 봤을 겁니다. 콜백 안에서 관찰 대상의 크기를 다시 바꿔 무한 리사이즈가 유발될 때 나옵니다. 예를 들어 폭이 줄면 폰트를 키우는데, 그게 다시 높이를 바꾸는 식이죠.

  • 피하는 법: 콜백 안에서 관찰 요소의 크기에 영향 주는 스타일을 즉시 바꾸지 말 것.
  • 부득이하면 변경을 requestAnimationFrame으로 다음 프레임에 미루기.
  • 크기 변화가 실제로 유의미할 때만(임계값 비교) 처리하기.

어디에 쓰나

진가는 '컨테이너 기준 반응형'에 있습니다. 미디어 쿼리는 화면 크기만 보지만, ResizeObserver는 컴포넌트가 놓인 실제 공간에 반응합니다. 같은 카드 컴포넌트가 넓은 자리에선 가로 배치, 좁은 자리에선 세로 배치가 되게 만들 수 있죠. CSS 컨테이너 쿼리로 해결되는 경우가 늘었지만, 캔버스 리사이즈나 JS 계산이 얽힌 상황에선 여전히 ResizeObserver가 필요합니다.

자주 묻는 질문

window.resize 이벤트로 대체 안 되나요?

안 됩니다. window.resize는 뷰포트(창)가 바뀔 때만 발생합니다. 창은 그대로인데 사이드바가 접혀 콘텐츠 영역만 넓어진 경우엔 이벤트가 오지 않아요. 요소 단위 변화를 잡으려면 ResizeObserver가 맞습니다.

컨테이너 쿼리가 있는데 왜 이걸 쓰나요?

순수 스타일 전환이면 CSS 컨테이너 쿼리가 더 간결합니다. 하지만 크기에 따라 캔버스를 다시 그리거나, 값에 맞춰 JS 로직을 돌리거나, 텍스트를 재계산해야 한다면 콜백으로 자바스크립트가 개입할 수 있는 ResizeObserver가 필요합니다.

성능 부담은 없나요?

ResizeObserver는 레이아웃 직후 한 번에 모아 콜백을 호출하도록 설계돼, 리스너를 남발하는 것보다 효율적입니다. 다만 콜백 안에서 무거운 작업이나 강제 리플로우를 유발하면 느려지니, 콜백은 가볍게 유지하고 필요하면 처리 시점을 다음 프레임으로 미루세요.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록