JavaScript의 비밀스러운 삶: Observer

발행: (2026년 3월 10일 PM 01:45 GMT+9)
3 분 소요
원문: Dev.to

Source: Dev.to

Timothy는 의자에 몸을 기대고 노트북 팬이 갑자기 거칠게 윙윙거리는 소리를 들었다. 그는 방대한 사용자 프로필 사진 그리드에 대한 lazy‑loading 기능을 방금 구현한 참이었다.

“스크롤이 완전히 부드러워,” Timothy가 화면을 두드리며 말했다. “어제 얘기한 { passive: true } 플래그를 사용했어. Compositor Thread가 완전히 언블록됐어. 그런데 CPU 사용량이 90%까지 급등하고, 노트북이 이륙 준비를 하는 듯한 소리가 나.”

Margaret는 커피를 들고 다가와 그의 보조 모니터에 표시된 성능 모니터를 살펴보았다.

“당신은 열차를 성공적으로 언블록했어요,” Margaret가 화면을 가리키며 말했다. “하지만 디스패처를 고문하고 있네요.”


스크롤 폴링의 문제점

lazy loading을 담당하던 코드는 스크롤 이벤트에 직접 연결돼 있었다:

const images = document.querySelectorAll('img[data-src]');

window.addEventListener('scroll', () => {
  images.forEach(img => {
    // Calculate exact geometry on every scroll tick
    const rect = img.getBoundingClientRect();

    // If the image enters the viewport, load it
    if (rect.top  {
  entries.forEach(entry => {
    // 2. Callback when the element intersects
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src; // Load the image

      // 3. Stop observing once the image has loaded
      observer.unobserve(img);
    }
  });
}, options);

// 4. Register all images with the observer
images.forEach(img => observer.observe(img));

브라우저는 이제 모든 공간 계산을 최적화된 C++ 엔진에서 수행한다. JavaScript는 실제로 이미지가 로드가 필요할 때 오직 깨어나고, 즉시 관찰을 해제해 반복 콜백을 방지한다.

장점 및 결론

  • CPU 사용량 감소 – 매 스크롤 틱마다 지속적인 레이아웃 계산이 없어진다.
  • 스크롤 부드러움 향상 – 메인 스레드가 렌더링 및 사용자 상호작용에 자유롭게 사용된다.
  • 코드 정리 – 옵저버 패턴이 로딩 로직을 하나의 잘 정의된 콜백으로 격리한다.

IntersectionObserver로 전환한 뒤 Timothy는 페이지를 새로 고치고 방대한 그리드를 스크롤했다. 스크롤은 여전히 부드럽게 유지됐고, 이미지가 화면에 들어오기 직전에 나타났으며, 노트북 팬 소리는 크게 줄어들었다.

0 조회
Back to Blog

관련 글

더 보기 »