ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 브라우저 미지원 시 requestIdleCallback 직접 구현하기
    Javascript | Typescript 2024. 11. 14. 09:50

    웹 개발을 하면서 성능 최적화에 신경 쓰다 보면 requestIdleCallback에 대해 들어보셨을 겁니다. 하지만 모든 브라우저에서 지원하지 않아 직접 구현해야 하는 상황도 발생하죠. 오늘은 requestIdleCallback이 무엇인지부터 직접 구현하는 방법까지, 그리고 React에서 사용할 때 주의할 점까지 함께 알아보겠습니다.

    🧐 requestIdleCallback이 뭐예요?

    간단히 말해, requestIdleCallback은 브라우저가 할 일이 없을 때 우리의 코드를 실행시켜주는 함수예요. 브라우저가 바쁠 땐 중요한 작업을 먼저 하고, 남는 시간에 덜 중요한 작업을 처리할 수 있게 도와주죠.

    requestIdleCallback(callback, options);
    • callback: 브라우저가 한가할 때 실행할 함수.
    • options: timeout을 설정해서 너무 늦게 실행되는 걸 방지할 수 있어요.

    🤔 왜 필요한 걸까요?

    사용자 경험 업그레이드

    • 반응성 향상: 사용자 인터랙션을 방해하지 않으면서 백그라운드 작업을 처리할 수 있어요.
    • 메인 스레드 효율화: 중요한 일과 덜 중요한 일을 나눠서 처리하니 메인 스레드가 효율적으로 돌아갑니다.

    비긴급 작업 처리

    • 로그 전송: 사용자 로그를 서버로 보낼 때 지금 당장 필요하지 않으니 유휴 시간에 처리하면 좋겠죠?
    • 데이터 프리페칭: 곧 필요할 데이터를 미리 가져올 때도 유용해요.

    🚀 어디에 쓰면 좋을까요?

    • 이미지 로딩: 사용자에게 바로 보이지 않는 이미지를 미리 로드.
    • 데이터 동기화: 서버와 데이터 동기화를 유휴 시간에 처리.
    • 분산 작업 처리: 큰 작업을 작은 단위로 나눠서 조금씩 처리.

    ⚠️ React에서 주의할 점

    상태 관리에 신중하세요

    • 비동기 업데이트 이슈: requestIdleCallback에서 상태를 업데이트하면 예기치 않은 리렌더링이 발생할 수 있어요.
    • 클린업 처리: 컴포넌트가 언마운트되면 콜백도 정리해줘야 합니다.

    브라우저 호환성 고려

    • 지원 브라우저 확인: 모든 브라우저에서 지원하지 않으니 폴리필이 필요해요.
    • 대체 방법 사용: setTimeout이나 requestAnimationFrame으로 대체할 수 있어요.

    🛠️ 직접 구현해봅시다!

    브라우저가 requestIdleCallback을 지원하지 않을 때를 대비해서 직접 만들어볼 수 있어요.

    폴리필 코드

    if (!window.requestIdleCallback) {
      window.requestIdleCallback = function (callback) {
        const start = Date.now();
    
        return setTimeout(function () {
          callback({
            didTimeout: false,
            timeRemaining: function () {
              return Math.max(0, 50 - (Date.now() - start));
            },
          });
        }, 1);
      };
    
      window.cancelIdleCallback = function (id) {
        clearTimeout(id);
      };
    }

    어떻게 동작하나요?

    • timeRemaining 함수: 남은 시간을 계산해서 반환해요. 기본적으로 50ms를 기준으로 합니다.
    • didTimeout 속성: 콜백이 시간 초과로 실행되었는지 표시하지만, 여기선 항상 false로 설정했어요.
    • cancelIdleCallback 함수: 등록한 콜백을 취소할 때 사용합니다.

      setTimeout을 사용한 이유는 직접 찾아보시는걸 추천드려욧 (hint: 이벤트루프)

    📝 실제로 써볼까요?

    예제: 작업 큐 처리

    const tasks = [...]; // 처리해야 할 작업 배열
    
    function processTasks(deadline) {
      while (deadline.timeRemaining() > 0 && tasks.length > 0) {
        const task = tasks.shift();
        task(); // 작업 실행
      }
    
      if (tasks.length > 0) {
        requestIdleCallback(processTasks);
      }
    }
    
    requestIdleCallback(processTasks);
    • 설명: 유휴 시간이 있는 동안에만 작업을 하나씩 처리합니다. 남은 작업이 있으면 requestIdleCallback을 다시 호출해요.

    🤷‍♂️ 추가로 알아두면 좋은 것들

    requestIdleCallback의 한계

    • 실행이 보장되지 않아요: 브라우저가 계속 바쁘면 콜백이 언제 실행될지 모릅니다.
    • timeout 옵션 활용: 너무 늦게 실행되는 걸 방지하려면 timeout을 설정하세요.

    다른 대안은 없을까요?

    requestAnimationFrame과 비교

    • requestAnimationFrame: 다음 화면 그리기 전에 실행되니 주로 애니메이션에 사용해요.
    • requestIdleCallback: 브라우저가 한가할 때 실행되니 백그라운드 작업에 좋아요.

    setTimeout과 비교

    • setTimeout: 일정 시간 후에 실행되지만, 브라우저 상태와는 무관해요.
    • requestIdleCallback: 브라우저의 유휴 시간에 맞춰 실행됩니다.

    최신 동향은?

    • 스케줄링 API 등장: React의 Scheduler 같은 라이브러리가 더 정교한 작업 스케줄링을 가능하게 해줘요.
    • 커뮤니티 의견: requestIdleCallback의 불확실성 때문에 다른 방법을 선호하는 개발자도 있어요.

    🌐 브라우저 지원 현황

    • Safari는 지원되지 않아 직접구현 또는 폴리필을 사용하셔야 합니다.

    📚 참고 자료

    마치며

    requestIdleCallback은 브라우저의 유휴 시간을 활용해 성능을 최적화할 수 있는 멋진 도구입니다. 하지만 호환성 문제와 불확실한 실행 시간 때문에 사용에 주의가 필요합니다.

Designed by Tistory.