Safari seems to throttle timers extremely aggressively in service workers. If I run this code: let previous = Date.now(); const interval = 1000; setInterval(() => { const now = Date.now(); const separation = now - previous; previous = now; console.log("tick", separation); }, interval); most ticks run after [interval + 10,000 ms] -- e.g. 1000 ms runs at 11,000 ms and 100 ms runs at 10,100 ms. Sometimes they run closer to the actual [interval], when the main page is doing work. Disabling "DOM Timer Throttling" and "Hidden Page Timer Throttling" has no effect. The same code in the main browser thread runs when expected (just after [interval]). Edge, Firefox and Chrome run the timers when expected in service workers. This is a problem for our application because we use timers to batch multiple HTTP requests into fewer HTTP requests. Consequently, our batched HTTP requests are delayed up to 10 seconds. (Safari v 11.1 / 13605.1.33.1.4)
Probably our timer throttling code that kicks in because the service worker does not have any visible page.
<rdar://problem/40219038>
<rdar://problem/40219039>
Do you have a test page? I have trouble reproducing. I see there interval very very close to 1000: CONSOLE MESSAGE: line 14: 1004 CONSOLE MESSAGE: line 14: 1000 CONSOLE MESSAGE: line 14: 1002 CONSOLE MESSAGE: line 14: 1003 CONSOLE MESSAGE: line 14: 1000 CONSOLE MESSAGE: line 14: 1006
I suspect this could be throttling outside WebKit known as AppNap. If I look at Activity Monitor, I see that the service worker process gets App Napped after ~30 seconds, I believe this impacts our timers as well. I'll look into preventing App Nap.
(In reply to Chris Dumez from comment #5) > I suspect this could be throttling outside WebKit known as AppNap. If I look > at Activity Monitor, I see that the service worker process gets App Napped > after ~30 seconds, I believe this impacts our timers as well. I'll look into > preventing App Nap. To confirm that this is the issue you are experiencing, you can disable App Nap via: defaults write NSGlobalDomain NSAppSleepDisabled -bool YES
Created attachment 340355 [details] Patch
Comment on attachment 340355 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=340355&action=review > Source/WebKit/UIProcess/ServiceWorkerProcessProxy.cpp:113 > + // Prevent App Nap for Service Worker processes. > + setProcessSuppressionEnabled(false); I think we want a FIXME with a link to a bugzilla bug that says Service Workers should nap if all their clients are napping. It's not a high priority bug, but it's good to clarify that's the design that we think would be best.
Created attachment 340359 [details] Patch
Comment on attachment 340359 [details] Patch Clearing flags on attachment: 340359 Committed r231771: <https://trac.webkit.org/changeset/231771>
All reviewed patches have been landed. Closing bug.
Thanks for the fast fix! `NSGlobalDomain NSAppSleepDisabled -bool YES` fixes the issue, so I assume the patch works as well.
(In reply to Zach Bjornson from comment #12) > Thanks for the fast fix! `NSGlobalDomain NSAppSleepDisabled -bool YES` fixes > the issue, so I assume the patch works as well. If you'd like, you can verify my fix by resetting this defaults and try this build: https://s3-us-west-2.amazonaws.com/minified-archives.webkit.org/mac-highsierra-x86_64-release/231772.zip which contains my fix. It'd be useful to make sure everything behaves as expected now.