ARTICLE · 2026년 9월 11일
브라우저 타이머가 백그라운드에서 느려지는 이유
웹 타이머를 켜 두고 다른 탭에 갔다 오면 숫자가 밀려 있는 경험이 있을 겁니다. 브라우저가 고장 난 것이 아니라 일부러 그렇게 합니다. 왜 그러는지, 어떤 타이머가 틀리고 어떤 타이머가 안 틀리는지, 그리고 PiP 창이 이 문제를 어떻게 비켜 가는지 설명합니다.
01
다른 탭에 갔다 오면 숫자가 밀려 있다
10분 타이머를 켜고 다른 탭에서 5분쯤 일하다 돌아왔는데 타이머는 7분 남았다고 합니다. 실제로는 5분이 남았어야 합니다. 몇 번 겪으면 웹 타이머를 믿지 않게 됩니다. 이 현상은 특정 사이트의 버그가 아니라 브라우저의 설계에서 옵니다. 그리고 설계를 알면 피할 수 있습니다.
02
브라우저는 보이지 않는 탭의 일을 늦춥니다
웹 페이지가 "1초 뒤에 이 코드를 실행해 달라"고 브라우저에 요청하는 방법이 setTimeout과 setInterval입니다. 타이머 화면을 매초 갱신하는 코드는 거의 모두 이 둘 위에 있습니다. 그런데 브라우저는 이 요청을 탭이 보일 때만 성실하게 들어줍니다.
이유는 배터리와 CPU입니다. 열려 있는 탭 수십 개가 뒤에서 매초 코드를 돌리면 노트북이 뜨거워지고 배터리가 빨리 닳습니다. 그래서 브라우저들은 보이지 않는 탭에 제한을 걸어 왔습니다.
- 2017년, Chrome 57뒤에 있는 탭의 타이머는 평균 초당 한 번까지만 깨어나도록 제한했습니다. 1초보다 짧은 간격으로 갱신하던 페이지는 이때부터 뒤에서 느려졌습니다.
- 2021년, Chrome 88탭이 5분 이상 숨겨져 있으면 연쇄적으로 예약되는 타이머를 1분에 한 번까지만 깨웁니다. 매초 갱신하던 타이머는 뒤에서 1분에 한 번만 움직이게 됩니다.
- Firefox와 Safari정확한 규칙은 다르지만 방향은 같습니다. 보이지 않는 탭의 타이머는 늦춰지고, 모바일에서는 아예 멈추기도 합니다.
이 규칙은 앞으로 더 엄격해지면 엄격해졌지 느슨해지지 않을 겁니다. 그러니 타이머는 브라우저가 늦춰도 틀리지 않게 만들어야 합니다.
03
1초마다 1을 빼는 타이머가 틀리는 이유
가장 단순한 타이머는 이렇게 만듭니다. 남은 초를 600으로 두고, 1초마다 1을 뺍니다. 화면에는 남은 초를 분과 초로 바꿔 보여 줍니다. 탭이 앞에 있을 때는 잘 됩니다.
탭이 뒤로 가면 문제가 시작됩니다. 브라우저가 "1초마다"를 "1분마다"로 바꾸면, 코드는 여전히 한 번 깨어날 때 1만 뺍니다. 실제로는 60초가 지났는데 타이머는 1초가 지났다고 믿습니다. 5분 뒤에 돌아오면 타이머에는 5초쯤만 흐른 것으로 나옵니다. 흐른 시간을 재는 게 아니라 깨어난 횟수를 세고 있었기 때문입니다.
탭이 앞에 있어도 미세하게 어긋납니다. "1초 뒤"라는 요청은 "최소 1초 뒤"라는 뜻이라, 브라우저가 바쁘면 1.02초 뒤에 실행됩니다. 1시간이면 수십 초가 쌓입니다. 요리 타이머에는 상관없지만 시험 시간을 재는 데는 문제가 됩니다.
04
종료 시각을 저장하고 매번 다시 계산하기
고치는 방법은 단순합니다. 시작 버튼을 누른 순간 끝나는 시각을 저장합니다. 지금이 14시 00분 00초이고 10분 타이머라면 종료 시각은 14시 10분 00초입니다. 이후 코드가 깨어날 때마다 하는 일은 하나입니다. 종료 시각에서 현재 시각을 빼서 남은 시간을 구하고, 그것을 화면에 그립니다.
이렇게 하면 브라우저가 코드를 1초마다 깨우든 1분마다 깨우든 결과가 같습니다. 깨어나는 순간의 현재 시각이 정확하기 때문입니다. 뒤에 있는 동안 화면 숫자가 1분에 한 번만 바뀌는 것은 사실이지만, 탭으로 돌아오는 순간 바로 다시 계산되어 실제 남은 시간이 표시됩니다. 표시가 늦은 것이지 시간이 틀린 것이 아닙니다.
PipTim은 이 방식입니다. 그래서 다른 탭에서 한참 일하다 돌아와도, 노트북이 잠깐 절전에 들어갔다 깨어나도 남은 시간이 밀리지 않습니다. 다만 아래에 적은 것처럼 이 방식으로도 못 넘는 벽이 있습니다.
05
그래도 남는 한계
- 탭을 닫으면 끝납니다종료 시각은 페이지가 살아 있을 때만 의미가 있습니다. 탭이나 브라우저를 닫으면 코드가 실행될 곳 자체가 없어집니다. 다시 열었을 때 이어서 보여 줄 수는 있어도, 그 사이에 끝났다면 알림은 울리지 않았을 겁니다.
- 기기가 잠들면 코드도 잠듭니다노트북 덮개를 덮거나 절전 모드에 들어가면 브라우저 자체가 멈춥니다. 깨어나면 종료 시각 기준으로 바로 맞춰지지만, 잠든 사이에 끝났다면 알림은 깨어난 뒤에야 울립니다.
- 모바일은 더 엄격합니다모바일 브라우저는 앱이 뒤로 가면 자바스크립트를 아예 멈추는 경우가 많습니다. 화면을 켜 두거나 PiP 창을 띄우지 않으면 알림 시점을 보장할 수 없습니다.
그래서 시험 종료, 약 복용, 주차 정산처럼 놓치면 손해가 큰 일에는 운영체제 알람을 함께 걸어 두는 것이 맞습니다. 웹 타이머는 남은 시간을 보여 주는 데 강하고, 운영체제 알람은 정해진 시각에 반드시 울리는 데 강합니다. 둘은 경쟁 관계가 아닙니다.
06
알림음이 안 나는 이유는 또 다릅니다
타이머는 정확한데 소리가 안 나는 경우가 있습니다. 이건 스로틀링이 아니라 자동 재생 정책 때문입니다. 브라우저는 사용자가 페이지와 한 번도 상호작용하지 않았다면 소리를 내지 못하게 막습니다. 광고가 멋대로 소리를 내는 것을 막기 위한 규칙인데, 타이머 알림음도 같은 규칙에 걸립니다.
PipTim에서 시작 버튼을 직접 누르는 것이 그 상호작용입니다. 그래서 시작 버튼을 눌러 시작한 타이머는 소리가 나고, 공유 링크로 설정만 불러온 상태에서는 시작 버튼을 눌러야 소리가 납니다. 그 밖에 소리가 안 나는 원인은 탭 음소거, 기기 음량, 방해 금지 모드 순으로 확인하면 됩니다. 도움말에 순서대로 정리해 두었습니다.
07
PiP 창이 이 문제를 비켜 가는 방식
스로틀링의 기준은 "보이는가"입니다. Picture-in-Picture 창은 항상 보이는 창입니다. 다른 창 위에 떠 있고 사용자가 보고 있으니, 브라우저가 그 창의 갱신을 늦출 이유가 없습니다. 원래 탭이 뒤에서 늦춰지더라도 종료 시각 기준으로 계산하는 타이머는 다음 갱신에서 바로 맞춰지고, PiP 창의 숫자는 매초 움직입니다.
더 실용적인 이유도 있습니다. 백그라운드 문제의 절반은 기술이 아니라 잊어버리는 것입니다. 타이머가 정확해도 안 보면 소용이 없습니다. 작은 창이 시야 안에 있으면 시간이 정확한 것과 별개로 시간을 의식하게 됩니다. 다른 창 위에 띄우는 여러 방법은 따로 정리한 글에 있습니다.