I have a web application to be run on mobile phones that when open continuously generates data (a few kilobytes every few seconds or every few minutes depending on settings) and needs to push it to a server in real time. No data is ever sent from the server to the browser.
My main concern is to make this submission battery efficient, a few seconds of delay is totally fine.
I envisaged two solutions:
Periodically do a POST to the server with the data (to avoid having a permanent connection to maintain)
Have an open websocket and periodically send messages (to avoid the weight of an http request)
Which one is the most efficient for the battery? Are there other strategies that I am missing?
Actually my app will be hosted on heroku, which does not supports websockets yet, resulting in long polling, thus for the moment I'll assume it is better to POST on demand, but I am wondering if it could be an option in the future (or maybe this assumption is wrong).
Android
On Android devices, there are three different network radio states as the documentation says:
The state machine for a typical 3G network radio consists of three
energy states:
Full power: Used when a connection is active, allowing the device to transfer data at its highest possible rate.
Low power: An intermediate state that uses around 50% of the battery power at the full state.
Standby: The minimal energy state during which no network connection is active or required.
While the low and idle states drain significantly less battery, they
also introduce significant latency to network requests. Returning to
full power from the low state takes around 1.5 seconds, while moving
from idle to full can take over 2 seconds.
The device changes from Full to Low after an idle time of 5sec, then from Low to Standby after another 12sec.
The above link also covers some best practices for battery friendly connections, although it doesn't say anything specific about Websockets.
iOS
I couldn't find such specific documentation on iOS devices, but the model seems to apply in a similar way:
Cellular and Wi-Fi radios are designed to power down when there is no
activity. Depending on the radio, though, doing so can take several
seconds. If your app transmits small bursts of data every few seconds,
the radios may stay powered up and continue to consume power, even
when they are not actually doing anything. Rather than transmit small
amounts of data more often, it is better to transmit a larger amount
of data once or at relatively large intervals.
So what?
In general, you should probably use short POST requests and send data as seldom as possible, so the radio can power down in between.
Related
I'm building a pwa for a client that will list upcoming tasks for their employees. They will often be in areas with poor mobile service so the intention is that records are downloaded whenever they have data and then loaded locally from indexeddb.
My original intention was to use "periodic sync" until I realised that the maximum refresh time was once every 12 hours.
Next I moved onto regular background sync, with the js app sending a sync request to the service worker, and the service worker running the functionality on ExtendableEvent.waitUntil as in Google's background sync example:
self.addEventListener('sync', function(event) {
if (event.tag == 'myFirstSync') {
event.waitUntil(doSomeStuff());
}
});
What I've found however is that event.waitUntil only seems to re-attempt the call every 5 minutes and I want a much faster refresh rate (more like every 30 seconds).
I kind of have 2 questions - first, is it possible to speed up the retry rate on waitUntil.
Perhaps more importantly, is this even a helpful strategy? It seems to me that my app could just repeatedly call the update function without even bothering the service worker. What advantage do I actually get from background sync?
Is there anything else in the pwa toolkit that would better suit my needs?
The benefit of (regular, "non-periodic") background sync is that the lifetime of the retries extend beyond the lifetime of your web app being open. Once the sync eventually succeeds, you could do something like show a notification (assuming the user has granted permission) that will take the user back to your web app to continue working.
Because this feature involves running code in the background, with the browser open but the web app potentially closed, there are limits imposed by the browser on how often the code will run. You can't increase the frequency of the retry attempts.
But you can definitely implement retry logic outside of the context of the service worker and background sync, by running code at the frequency you desire from within the context of your web app itself. But in that scenario, the retries will cease as soon as the user closes your web app.
I want to make a custom tracking system for web events. I have looked into multiple per-excsiting systems, but I want something terribly simple - yet very accurate.
I want to be able to track the following:
Page view even
Time on that page
or:
Video started playing event
Time of video watched
My first initial thought was to do a simple javascript reporting back to the server, but what happens if the user closes the window? How do I know they stopped viewing? And how can I get accurate measurements down to 1/10th of a second? So I thought of a websocket solution, as it know when a user has discounted. I ended up with Socket.io, but I want to make sure there is no better or smarter way to achieve this?
How would you approach his challenge? What is the smartest way to engineer this?
A Websocket connection which reports back to the server frequently was my first thought as well, but if you send 10 messages every second, even that might be too much for a websocket, especially when connectivity isn't top-notch.
Since the server doesn't require the information absolutely immediately, consider batching requests instead - save/update the information into Local Storage every 0.1 seconds, but don't send it to the server then - instead, every 30 or 60 seconds, or on pageload, take the current data in Local Storage and send it to the server, and clear Local Storage so that the next request a minute from now doesn't send duplicate data.
We use Google analytics with Google Tag manager for our ecommerce platform based to track the conversion, etc.,
In the thank you page, its used to track the order value and the revenues.
Consistently we see a difference of about 15 to 20 % difference between GA data and the data from the core platform.
Tried to find a pattern among the missed orders but couldnĀ“t ascertain one easily. The GA recorded orders include devices like Desktop, tablet and mobile and we see different browsers too.
Need inputs to analyze this better.
Note: Thank you page is loaded by a redirect from the payment gateway system
15-20% difference is not good at all. Google says you should expect better than 95% accuracy, and to keep at it if you're not getting those numbers.
Note: The more "techy" crowd that your website has, the more folks you'll run into "Do not track" or with Ad-Blocking tech in their browser. Normally, you'd want to try to baseline that difference using device category filters to see if the gap is bigger for desktop (most phones/tablets don't use ad-blocking).
First, question. If the user lands on the thankyou page, and hits the refresh button, does it send another "conversion" to GA? IF so, you want to make sure that you build in logic that prevents duplicate conversions to be sent if the user was not making duplicate purchases. A browser refresh is not a purchase, don't record it as such.
Second, if the page takes forever to load, or you have users that have bad internet, then that could increase the difference. They might be closing the browser or exiting site before GA client has a chance to send the final conversion to the server. So how is the performance of your thankyou page?
Are you sure you're looking at the correct business data? I've been told GA numbers are off by the business before and it turned out they messed up their own query in the transaction system (and they had been doing so for years!). It is a long shot, but if you feel super confident about your GA measurement setup, then run it by the folks giving you the transaction numbers.
Finally, if you can't get the difference down then move to the Measurement Protocol server-side implementation of GA. You simply need to record the IP address of the user and their GA client id, and then construct an HTTPS GET request using the Measurement Protocol fields for a valid hit. Server side measurement is the most accurate way to do this, but requires code updates in the ecommerce platform itself.
Just to set the background, I'm working on an app with Cordova + Sencha Touch and NodeJS + MongoDB as backend. Now I need to have some devices (tablets or smartphones) send some data to a central device (pc), that would to be done periodically or on demand. I'm trying to figure out what the best way of doing that is.
Just to make myself clear...
Device 2 <------ Device 0 -----> Device 1
|
|
v
Device 3
So with that illustration in mind: I'd need to have Device 1, 2 and 3 (tablet or smartphone) send their current location (along with some other information) to Device 0 (pc, server, etc). Keep in mind that there's actually gonna be a lot more than 3 devices, say 1500 or 2000.
What I thought was have them send that data periodically to a database and then query that database whenever it's needed. That would have to be done once every 30 seconds (or less) though.
I really have no idea of what the best way of doing this would be though, I suppose I could achieve this by setting a counter on the device's app and having it send the data to the database, but I'm certain there has to be some more efficient way.
The other option is having them send their data on demand, but that seems like more workload as there's a ton other devices (hopefully in the 10s or 100s thousands) that will have to ask those 2k devices for that data, and that could be whenever the user wants to.
So, are there any other ways of doing this that I'm missing?
EDIT
Just for the record, I ended up chosing the first option. Just record whatever status I needed on my db and query whenever I need to check for changes.
In our application, we are painting navigation component using JavaScript/jQuery and because of authorization, this involves complex logic.
Navigation component is required on almost all authenticated pages, hence whenever user navigates from one page to another, the complex logic is repeated on every page.
I am sure that under particular conditions the results of such complex calculations will not change for a certain period, hence I feel recalculation is unnecessary under those conditions.
So I want to store/cache the results at browser/client side. One of the solution I feel would be creating a cookie with the results.
I need suggestions if it is a good approach. If not, what else can I do here?
If you can rely on modern browsers HTML 5 web strorage options are a good bet.
http://www.html5rocks.com/en/features/storage
Quote from above
There are several reasons to use client-side storage. First, you can
make your app work when the user is offline, possibly sync'ing data
back once the network is connected again. Second, it's a performance
booster; you can show a large corpus of data as soon as the user
clicks on to your site, instead of waiting for it to download again.
Third, it's an easier programming model, with no server infrastructure
required. Of course, the data is more vulnerable and the user can't
access it from multiple clients, so you should only use it for
non-critical data, in particular cached versions of data that's also
"in the cloud". See "Offline": What does it mean and why should I
care? for a general discussion of offline technologies, of which
client-side storage is one component.
if(typeof(Storage)!=="undefined")
{
// this will store and retrieve key / value for the browser session
sessionStorage.setItem('your_key', 'your_value');
sessionStorage.getItem('your_key');
// this will store and retrieve key / value permanently for the domain
localStorage.setItem('your_key', 'your_value');
localStorage.getItem('your_key');
}
Better you can try HTML 5 Local Storage or Web SQL, you can have more options in it.Web SQL support is very less when compared to Local Storage. Have a look on this http://diveintohtml5.info/storage.html