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.
Related
I am currently using reactJS version "15.0.1" in my web application. In one of the feature we need to keep pooling some information continuously after each 2 seconds. So we receive the response which is List of some object(700/1000 items in list) which we update and show in the react web application. The Problem is after some time the application becomes unresponsive and takes too much time for any operation. On profiling I found its render, batch updates and dispatch event in react js that takes the longest time. Is there any recommended way to get away with the performance issue in react. The feature needs to be refreshed every 2 seconds and list size is more than 1000 items each time.
The performance issue is observed in IE and Chrome browser.
It's hard to tell without seeing your code, maybe you have a memory leak? You could try to mark your objects for garbage collection at the end of your methods.
listOfSomeObject = null;
Here is a good article capturing some methods to identify and fix memory leaks.
https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/
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);
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
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
I wonder if this code is going to put load on the client since the timeout is so long?
//and update this again in a bit
setTimeout(function() {
updateWeather(lat,lng);
}, 60000);
Not that code alone. The system idles for that one minute. As long as updateWeather doesn't have severe performance issues and the interval is short, setTimeout won't be a product (and I believe you mean setInterval, not setTimeout for recurring checks)
The 60 second timer is implemented by magic in the OS: it basically adds no CPU load during the 60 seconds it is waiting.
I guess updateWeather() is polling an external resource, so the answer to your question is a simple "no, it is fine". (As the weather does not change that often, I'd make it 5 minutes instead, see comment below on battery life.) (Even better: see if the weather data provider gives you a field telling you when the next update will be, and use a setTimeout based on that.)
In other situations, for instance if you have been collecting some kind of data for those 60 seconds, and then go and process it in one go, this could cause a peak of heavy load. Which might be noticed by the user (e.g. all animations go jerky once every 60 seconds). In that case it is better to use a 5 second timer, and process 5 seconds worth of data at a time.
Conversely, if you are using the network on a mobile device, you have to consider battery life: wake-up-and-find-a-connection can dominate. So extending a polling time from 60 seconds to 120 seconds can literally double battery life. Ilya Grigorik has a very good chapter on this in his book, High Performance Browser Networking, http://shop.oreilly.com/product/0636920028048.do
...here it is: http://chimera.labs.oreilly.com/books/1230000000545/ch08.html#ELIMINATE_POLLING
One thing to keep in mind, in addition to the other answers, is the affect that the closure of in-scope variables might have on memory performance. If you've got a gajillion objects being referenced by variables in the scope(s) above your setTimeout callback, those objects may live as long as the callback is queued. That is not something we can tell from the code you posted and so no answer can be definitively given to your question. Also, if your setTimeout is being called multiple times, it will create a closure for each one, effectively duplicating the environment and taking up your heap space.
The answer to your question depends on:
The device you execute this on
The environment - how many times do you execute this
A standalone setTimeout would not hurt the browser; however, if you are doing the same thing repeatedly, it would make a difference.
Have a look at the following website for more insights...
http://ejohn.org/blog/analyzing-timer-performance/