Keeping $intervals synced up - javascript

I have an application with server requests to detect when something has happened, at which point it sets a countdown to something happening. If I have the app opened on multiple tabs/devices, they all get the event at the same time, but their countdowns differ in length. Is there a way to fix this?
I saw elsewhere that setInterval only calls the function if the tab is active, does $interval work similarly? All tabs seem to still get updated without being active, just at slightly (5-10%) different rates.
I was considering instead of starting a countdown that the application saves the current Date and then does a very fast interval constantly checking if the proper time has elapsed since that date, but that seems computationally intensive, though the rest of the application is lightweight so that wouldn't be a problem per se.
The interval itself is super fast/simple:
countdownTimer = $interval(function () {
$scope.countdown--;
}, 1000);

Related

Best practice for keeping timer running in PWA

I am building a progressive web app using React, the concept of which revolves around keeping a timer running.
For context, the app is for home-brewers to keep track of when hops and other additions need to be added to their boil during their brew. Additions are added with a certain amount of time remaining in the boil, i.e. 1 oz Citra hops at 20 minutes remaining.
I'm using JavaScript's setInterval to "tick" the timer, which is an elapsedSeconds state property that drives the rest of the application.
The problem I'm running into is when the timer stops ticking. If I let the app run, the screen will eventually lock, or I'll switch apps, etc. The service worker will continue running, and the timer will continue to tick, for a short time (about 10 minutes from what I can tell in testing?)
My thought is that I will store an epoch time in state, that represents the time when the timer started. That way, when a user "returns" to the PWA, I can compare the current epoch time against the stored startingEpochTime to get the elapsedSeconds back. But I don't want to do this comparison at every "tick" if I don't have to. Ideally, this comparison would only run when the user is returning to the application from some other context, after the service worker has already stopped processing.
What I'm looking for is the correct way to do this. Would window.onload work in this instance? If I switch apps to another app for 20 minutes then switch back to my timer app, is that method run again? Looking for the best practice for this sort of scenario, or any idea that might help me out.
As of 2022 there is no way of scheduling tasks or keeping a timer running when a PWA is moved into the background.
To everyone who wants this functionality, please star and comment on the Google issue requesting it to motivate them to act: https://bugs.chromium.org/p/chromium/issues/detail?id=889077
Here's a couple of pointers that can help:
The general solution to what you describe is the Wake Lock API, which is the process of being design and specified, but is not available anywhere by default (yet).
In terms of what's currently implemented, there are pretty reliable ways of at least detecting when your web app goes into the background and goes back into the foreground using the Page Lifecycle API events. Once you're reliably detecting when you've come back to the foreground, a technique like what's mentioned in the comments about comparing the start time to the current time sounds about right.

Best way to program multiple alarms

I am creating an application that allows users to set multiple alarms.
The two ways I can think of doing is:
Store alarms as rows in a table and have a cron job check them every
minute. However, this means that the alarms will only be checked
every minute while some users may want it to be checked at a finer
resolution.
Create a new timer object for each new alarm that will call itself
with a setTimeout function. But if the app crashes then the alarms
are lost.
You can give a try to node-scheduer.
Very much similar to the cronjob. But the application must be kept on running.
It executes an event on a given interval. Make sure the job is executed after the desired interval every time and Put the alarm functionality there.

is Javascript's setInterval loop a resource hog?

I'm designing an app to run on very low spec machine..and i needed it to be efficient as possible..
I needed to issue around 10 intervals at every second that simply makes an ajax call.. and then does a few add/remove classes and (think of it as SERVER Status monitor)
I know in FLASH (oh good old flash days) having a lot of intervals can cause processor spikes .. so i'm very conservative with issuing setIntervals in AS 2.0 before.
I was wondering if this is the same case with JS? or is it alright for JS to have a bunch of intervals (that does lightweight tasks) running? I noticed a lot of sites do this , even facebook has tons of intervals running, loading scripts, etc..
And oh, for one interval, I wanted to run it at 50ms (it loads as status.php link) ... this ok?
I could probably optimize my interval calls, no problem but i'm just wondering how "heavy" or "lightweight" background intervals are in JS..
Thanks all
10 intervals at every second meaning a call every 100ms should not be an issue in my opinion, but if you ask me I would fire a call every 250ms.There is not much difference between the two that the user will notice.
Also make sure that there is a mechanism to handle long running response from server in case there is a delay and stop the interval firing if there is drag.
As a matter of personal feeling, I tend to prefer setTimeout over setInterval -- to the point I don't use setInterval at all.
The issue that you might run into is if one process takes longer than it should -- let me give you an imaginary situation:
window.setInterval(takes100msToRun, 50);
window.setInterval(takes50msToRun, 50);
window.setInterval(takes20msToRun, 50);
The problem is that the first interval will take longer than it should, so the second two interval requests are now behind and the browser will try to catch up by running them as quickly as then can. The second interval takes 50ms, -- so its still running behind when the third interval hits.
This creates an ugly situation that can lead to a lot of drag.
On the other hand, if you setTimeout, then you aren't say "Run this every 50 ms", but rather "Run another one of these 50ms from we finish." (Assuming, of course, that the functions set up another setTimeout to re-execute.)
It is absolute rubbish for things that need good clock timing, but its superior for everything else.
setTimeout and setInterval will affect performance, but little.
Since there are lots of functions triggered/listening/running in the browser.
Even a tiny operation like move your mouse to vote up for this answer, there are thousands of events got triggered, and tens of functions start running.
Don't use setInterval. As a matter of fact, the library underscore doesn't use it either.
See how they implement the _.throttle without setInterval.
http://learningcn.com/underscore/docs/underscore.html#section-66

Javascript Timed Notifications - setTimeout, setInterval

I am creating a web app that allows users to manage a calendar (CRUD events, tasks, reminders etc...)
And I am trying to implement a feature where they will receive a popup reminder x-minutes before the event/task. From my understanding there is really only one way to do this with javascript:
On login, check for any upcoming events in the database (say in the next 12 hours) and create a setTimeout for the next event, when that setTimeout executes, check again for next event and so on...
My question is, will having multiple setTimeouts (10+) running in the background during user interaction slow down the performance of my app?
Is there a better way to handle popup notifications on the client side? Push Notifications? Any suggestions would be greatly appreciated!
My question is, will having multiple setTimeouts (10+) running in the background during user interaction slow down the performance of my app?
In those numbers, no. (Depending on how + the + in 10+ is. I mean, I expect a million probably would be an issue.)
The other approach would be to have a single timer that you use (say, per minute) to check for notifications that should occur as of that minute. E.g.:
function notifyForThisMinute() {
// Notify user of things we should notify them of as of this minute
// ...
// Schedule next check for beginning of next minute; always wait
// until we're a second into the minute to make the checks easier
setTimeout(notifyForThisMinute, (61 - new Date().getSeconds()) * 1000);
}
notifyForThisMinute(); // First call starts process
This depends on the browser (or more specifically, it's javascript engine) and apparently even OS.
Neil Thomas (while working on GMAIL mobile) and John Resig have analyzed timers.
One of the more noticeable things to look out for is how often the timer runs per given time-interval (say every 200ms or once every 10 minutes..).
Thomas:
With low-frequency timers - timers with a delay of one second or more - we could create many timers without significantly degrading performance on either [an Android G1 or iPhone 3G]. Even with 100 timers scheduled, our app was not noticeably less responsive. With high-frequency timers, however, the story was exactly the opposite. A few timers firing every 100-200 ms was sufficient to make our UI feel sluggish.
Thomas:
Keep in mind that this code is going to execute many times every second. Looping over an array of registered callbacks might be slightly "cleaner" code, but it's critical that this function execute as quickly as possible. Hardcoding the function calls also makes it really easy to keep track of all the work that is being done within the timer.
Resig:
Once you start moving into the range of 64-128 simultaneous timers, you’re pretty much out of luck in most browsers.
One might also have a look at Chronos

How to make a script that polls every second with POST or GET without lag?

I want to make a notification center for my control manager system. If I use something like this:
$(function(){
setInterval(function(){
$.post("url", { data: 'value' }, function(result){
// check for updates
});
}, 1000);
});
the page is lagging all the time. Isn't it possible to do something like this 'on the background'? Without loading or lagging issues? If that is possible, that would be great! I tried several things but didn't have much effect.
you should increase your interval time to something more reasonable than 10 times/second. maybe something like once per second with a value of 1000
What you are referring to is called long-polling. Without knowing what your code is doing to the page, it is hard to tell what it causing lag on the page. Even so, polling every second can put a big load on your server as you scale.
You will want to increase your time interval. Something like once every 3-10 seconds won't adversely affect the user experience. People will not notice unless you are making a shared document editing or drawing application. It sounds like you are simply pushing notifications.
If you want web "real time" notifications, use WebSockets. You will still need to implement long-polling for browsers that do not support WebSockets: details here under 'Browser compatibilities'.
HTML5 Rocks has a good intro to WebSockets.
If you want a guaranteed interval between your calls, instead of setInterval try using a setTimeout and call the same function that has your post/get code. Something like
function myTimeout() {
//your code for post/get
setTimeout(myTimeout, 1000);
}
What this does is guarantee the "Previous Interval" is complete before the next call to "myTimeout" which in turn has the post. This I believe, would not be guaranteed using setInterval, which in your case calls a function making the post every 1000 milli sec no matter what. With delays, the calls may not be spaced out by the desired interval(1000 milli sec).
This still does not guarantee a fixed interval between calls though(if the call/response takes longer time than the specified interval).
Read more at https://developer.mozilla.org/en-US/docs/Web/API/window.setInterval under the heading "Dangerous usage"

Categories

Resources