요약

  • W3C의 2015년 9월 첫 공개 초안은 requestIdleCallback을 제시했다. 페이지가 한가한 때 실행을 요청하면 브라우저가 시점을 고르고, IdleDeadline의 timeRemaining()으로 남은 시간을 가늠한다.
  • 2017년과 2025년 문서도 같은 역할 분담을 이어 간다. 페이지는 일을 잘게 나눠야 한다. 선택적인 시간 제한을 걸면 여유가 끝내 오지 않아도 오래 기다린 작업을 실행할 길이 열린다.

웹페이지는 ‘나중에 잠깐’ 할 일로 가득하다. 다음에 펼칠지도 모르는 화면을 준비하고, 데이터를 조금 계산하고, 로컬 기록을 정리한다. 하나씩 보면 부담이 작다. 그러나 모두가 브라우저의 같은 실행 순서를 차지하면 사용자가 누른 버튼은 자기 차례를 기다려야 한다. 화면을 그리는 일과 손가락에 답하는 일도 그 줄에 서 있기 때문이다. 뒤편의 집안일이 앞문을 막는 순간, 독자는 사이트가 느려졌다고 느낀다.

예전에는 setTimeout으로 다음 실행 시각을 정할 수 있었다. 문제는 타이머가 그 시각의 브라우저 사정을 모른다는 점이었다. 화면을 다시 그리는 중인지, 입력을 처리하는 중인지 알지 못하고 종을 울렸다. W3C가 2015년 9월 17일 공개한 첫 초안은 일정을 아는 쪽에 시간을 고르게 했다. 페이지가 requestIdleCallback을 호출하면 브라우저는 한가한 구간이 예상될 때 콜백을 부른다. 함께 전달되는 IdleDeadline은 지금 얼마나 시간이 남았는지 알려 준다.

핵심은 timeRemaining()이다. 페이지는 일을 조금 진행하고 남은 시간을 확인한 뒤, 시간이 다하면 다음 기회를 신청한다. 2015년 초안은 한 번의 한가한 구간에 50밀리초 상한을 두었다. 실제 여유는 새 입력이 들어오면 더 짧아질 수 있다. 그러니 긴 작업을 단지 ‘idle’이라는 이름의 함수에 넣어서는 해결되지 않는다. 트럭에 ‘소포’라고 써 붙여도 좁은 골목을 통과할 때는 여전히 트럭이다. 작업 자체를 멈출 수 있는 크기로 잘라야 한다.

첫 초안의 예시는 계산을 조금씩 정교하게 만드는 방식이었다. 몇 단계를 밟고 시계를 보고, 다음 호출에서 이어 간다. 별것 아닌 절차처럼 보이지만 판단의 위치를 정확히 보여 준다. 브라우저는 다음 화면과 입력의 압박을 안다. 반면 어떤 계산을 중간에 끊어도 괜찮은지는 페이지 제작자가 안다. 브라우저가 시간을 건네도 웹페이지가 일을 나눌 줄 모르면 짧은 틈은 쓸모가 없다.

2017년 1월 후보 권고안과 그해 10월 제안 권고안은 반대편 걱정도 다뤘다. 브라우저가 계속 바쁘면 뒤로 미룬 일은 영원히 부름을 받지 못할 수 있다. 페이지는 timeout을 지정할 수 있다. 시간이 지나면 콜백이 실행될 수 있고, didTimeout이 그 경로를 알려 준다. 오래 기다린 일을 꺼내는 비상문이다. 모든 스크립트가 그 문으로 밀려들면, 비상문 앞이 가장 붐비는 입구가 된다.

W3C의 공식 발표 이력에는 2015년 첫 초안과 2017년 단계, 이후 개정이 이어진다. 2025년 5월 21일 작업 초안도 브라우저가 한가한 구간을 판단하고 콜백에 남은 시간을 전하는 구조를 유지한다. 여러 해에 걸친 수정 뒤에도 질문은 단순하다. 모두가 쓰는 시계를 누가 보고, 각자의 밀린 일 가운데 무엇을 가져올지는 누가 정할 것인가.

사이트 운영자는 이 틈에 넣을 일을 고르는 데 실력을 보여 준다. 독자가 다음에 볼 가능성이 큰 화면을 미리 준비하면 기다림을 줄일 수 있다. 반대로 모든 모듈의 ‘급한’ 일을 틈마다 밀어 넣으면 페이지는 자신을 돌보느라 독자를 기다리게 한다. 사용자는 IdleDeadline이라는 이름을 볼 일이 없다. 누른 버튼이 바로 반응하고 다음 화면도 준비되어 있으면 충분하다. 작업대가 보이지 않을 만큼 자연스럽게 돌아가는 것이 이 약속의 성과다.