# 브라우저가 JavaScript 타이머를 스로틀링하는 이유

> Clean Markdown view of GeekNews topic #23210. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=23210](https://news.hada.io/topic?id=23210)
- GeekNews Markdown: [https://news.hada.io/topic/23210.md](https://news.hada.io/topic/23210.md)
- Type: news
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-09-22T10:59:01+09:00
- Updated: 2025-09-22T10:59:01+09:00
- Original source: [nolanlawson.com](https://nolanlawson.com/2025/08/31/why-do-browsers-throttle-javascript-timers/)
- Points: 16
- Comments: 0

## Summary

브라우저가 **JavaScript 타이머** 실행을 최소 4ms로 제한하는 이유는 **배터리 소모**, **사용자 경험 저하**를 막기 위한 조치이며, 백그라운드 탭이나 배터리 모드에선 이 제한이 더욱 강화됩니다. 개발자들은 이를 우회하기 위해 **MessageChannel**, **window.postMessage**, **Scheduler API** 등 다양한 대체 수단을 활용하고 있으며, 실제 벤치마크에서도 최신 대체 API들이 거의 지연 없이 동작함을 확인할 수 있습니다. 이러한 제약은 브라우저와 개발자 간 **자유와 통제의 균형** 문제로 이어지며, Scheduler API가 이를 절충하는 방향으로 표준화되고 있지만, 남용이 발생할 경우 추가 **브라우저 개입** 가능성도 염두에 둘 필요가 있습니다.

## Topic Body

- JavaScript에서 `setTimeout(0)`은 실제로 즉시 실행되지 않고 최소 **4ms 지연**되는 경우가 많으며, 이는 남용 방지를 위한 브라우저의 기본 제한임  
- 이런 제약은 웹사이트가 무분별하게 타이머를 남용하여 **배터리 소모**나 **인터랙션 저하**를 일으키는 것을 막기 위한 조치로, 배터리 모드에서는 16ms, 백그라운드 탭에서는 1초로 더 강하게 제한되기도 함  
- 개발자들은 `setTimeout`의 한계를 우회하기 위해 `setImmediate`, `MessageChannel.postMessage`, `window.postMessage`, `scheduler.postTask` 등 다양한 **대체 타이머 API**를 활용해왔음  
- 실제 벤치마크 결과, Chrome과 Firefox는 4ms 클램핑이 적용되지만 `MessageChannel`과 `scheduler.postTask`는 거의 지연 없이 동작하며, Safari는 `setTimeout`을 더 강하게 제한하는 특징을 보임  
- 근본적으로는 사용자 경험 보호와 개발자 자유 간의 균형 문제로, 현재는 **Scheduler API**가 표준화된 해법으로 자리잡고 있으나, 남용이 발생하면 새로운 **브라우저 개입(Intervention)** 이 도입될 가능성도 있음  
  
---  
### `setTimeout` 제한의 배경  
- `setTimeout(0)`이라도 **어뷰징** 때문에 실제 실행은 최소 4ms 뒤에 일어나는 경우가 많음  
  ```js  
  const start = performance.now()  
  setTimeout(() => {  
    // 약 4ms 후 실행됨  
    console.log(performance.now() - start)  
  }, 0)  
  ```  
- 이는 무분별한 반복 호출을 막아 배터리 소모와 렌더링 지연을 줄이기 위함  
- 일부 브라우저는 환경에 따라 제한을 강화함  
  - 배터리 모드: 구형 Edge에서는 16ms  
  - 백그라운드 탭: Chrome에서 최대 1초까지 지연  
  
### 다른 타이머 API의 등장  
- `setImmediate`: IE와 구형 Edge에서만 지원, 사실상 단종  
- `MessageChannel.postMessage`: 별도 채널을 통해 이벤트 루프에 작업 전달  
- `window.postMessage`: 성능은 좋지만 다른 스크립트와 충돌 위험 있음  
- `scheduler.postTask`: 최신 브라우저에서 지원되며 가장 안정적인 선택지로 평가됨  
  
### 벤치마크 결과 (MacBook Pro 2021, 101회 반복 측정)  
- Chrome 139: `setTimeout` 4.2ms, `scheduler.postTask` 0ms  
- Firefox 142: `setTimeout` 4.72ms, `scheduler.postTask` 0.01ms  
- Safari 18.4: `setTimeout` 26.73ms, `MessageChannel` 0.52ms, `window.postMessage` 0.05ms  
  
### `fake-indexeddb` 사례  
- IndexedDB는 이벤트 루프의 마이크로태스크 종료 직후 트랜잭션 자동 커밋을 원함  
- Node.js의 `setImmediate`는 이상적이지만 브라우저에서는 `setTimeout`이 비효율적  
- Chrome에서는 300ms 걸리는 작업이 브라우저에선 4.8초까지 늘어나는 문제 발생  
- 해결책으로 `scheduler.postTask`를 기본 사용하고, 호환성 위해 `MessageChannel`/`window.postMessage`를 폴백으로 채택  
  
### 브라우저 개입 논쟁  
- 한쪽은 타이머를 제한해야 개발자가 스스로를 보호할 수 있다고 주장  
- 다른 쪽은 개발자가 스스로 측정하고 최적화할 수 있도록 **자유를 보장**해야 한다고 주장  
- 결국 사용자 우선 원칙에 따라 브라우저는 남용 방지를 위해 개입(intervention)함  
- Scheduler API는 두 입장을 절충해, 개발자에게 세밀한 **작업 제어권**을 주면서 브라우저 렌더링 파이프라인과 정렬되도록 설계됨  
  
### 향후 전망  
- `postTask`와 `postMessage`는 당분간 스로틀링 없이 유지될 것으로 보임  
- 하지만 `user-blocking` 같은 높은 우선순위를 남용하면 다시 개입 가능성 존재  
- 장기적으로는 또 다른 `scheduler2` 같은 대체 API가 필요해질 수도 있음

## Comments



_No public comments on this page._
