Can I detect if a browser's network activity is idle? - javascript

In an angularJS app there is quite a big of latency between the user and the server (also bandwidth may be limited), so when the user requests a new page, it has to wait about 2-500ms for it to load.
I'm thinking of "preloading" model data, templates, scripts in the background, but intend to do so ONLY if there is no page requested by the user. If the user requests one specific page I'd like to stop the preloading process and load the resources explicitly requested by the user.
So my question boils down to:
Is there a way to make an ajax request "ONLY IF" there is no network activity?
Is there a way to "pause" currently running ajax requests? or
Is there a way to prioritize ajax requests?
Thanks,

Seems like https://nicedoc.io/pastelsky/network-idle-callback will be helpful for you.
It uses serviceWorker to observe network calls, and dispatch event when it senses network idle.
npm install network-idle-callback
Usage

Sounds like requestidlecallback is what you're looking for. There's also a package built on top that exposes an event you can listen to: https://github.com/choojs/on-idle

Related

Web - what is the differences between periodic sync and sync?

I came across two different types of sync in the background for PWAs sync and periodic sync. there are not many resources for them and existing resources do not explain enough with sample working codes.
so my main question is: are there any other logical differences between them other than frequency?
and my side question is: are they handling requests by themselves? I'm asking this because I want something more flexible, I mean I'm managing offline and online situations and saving data in IDB them I'm offline and I just need a background process to get my offline data from my custom IDB and send them to the server.
Here's a few use cases that can help illustrate the difference. Also keep in mind that as of Feb. 2021, the Background Sync is only available in Chrome and Chromium-based browsers, and Periodic Background Sync is only available in Chrome after a progressive web app has been installed.
Background Sync
The use case is retrying a failed update/upload operation (usually a POST or a PUT) "in the background" at a regular interval, until it succeeds. You could imagine, for instance, trying to upload a new photo to a social media site, but your network connection is down. As a user, you'd want that upload retried at some point in the future.
The API only provides the mechanism for triggering an opportunity to re-attempt the network operation, via a sync event in the web app's service worker. It's up to a developer to store information about the failed request (usually in IndexedDB) and actually resend it, and indicate whether the sync was successful or if it failed again.
(The workbox-background-sync library can help with the implementation details, if you'd rather not deal with everything yourself.)
Periodic Background Sync
The use case is refreshing caches "in the background" so that the next time a user opens your web app, the data is fresher than it otherwise would be. You could imagine an installed news progressive web app using periodic background sync to update its cache of top headlines each morning.
Under the hood, this works by invoking a periodicsync event in your service worker, and inside that event handler, you'd normally make a GET request to update something stored in the Cache Storage API or IndexedDB.

How to add headers to a browser request without any browser extensions?

Sometimes, one needs to add special headers to each request or specific requests made from a browser. The common approach to do this is by using browser extensions which allow us to modify request headers. Is there another way to do this, without any browser extension ?
PS - I have searched SO and not found a single post which actually suggests or shows how to do what I need.
Outside of APIs designed to make custom HTTP requests (XMLHttpRequest and fetch), it is impossible to add arbitrary HTTP headers to requests made by browsers using JS embedded in a page.
If you control the websites that you want this functionality on, you could achieve this by setting each application to install a ServiceWorker. In a nutshell, service workers run as a proxy server within your browser. They can do things like notify you of updates even if you don't have the website open.
Within a ServiceWorker you are able to set up event listeners that can do some asynchronous task on behalf of the client app. This includes the fetch event which is fired every time the web page makes a request.
Here's a write up on someone implementing a ServiceWorker who also needed to intercept network requests. You could follow most of this and just alter the logic when inspecting the request type. At that point you could add any special headers before dispatching on the applications behalf.
Theres no possibility to edit requests in existing DOM without using any external tools. The most suitable is Browser Extension which is editing the existing DOM and HTTP requests (XMLHttpRequest and fetch) done by JavaScript code.
Theres millions of possibilities to add headers to requests if the owner of website is you. And the solutions are different consider on what lib are you using for doing requests.
But in general it's not recommended to modify website data that is not yours.
The Browser Extension is the exact thing that you found for your problem.
Hope my comment will help you.

Service workers and page performance

I'm stuck at a wedding reception that I really don't want to be at and I'm driving, so obviously I'm reading about service workers. I'm on my phone so can't play about with anything but was thinking if they're a viable option for improving page performance?
Images are the biggest killer on my site and I'm half thinking we could use a service worker to cache them to help get page load times down. From what I can tell, the browser still makes the http request, it's just the response is from the SW cache, not the file location. Am I missing something here? Is there therefore any actual benefit to doing this?
While the regular http cache has a lot of overlap with ServiceWorker cache, one thing that the former can't handle very well is the dynamically generated html used in many client-side javascript applications.
Even when all the resources of the app are cache hits, there is still the delay as the javascript is compiled and executed before the app is usable.
Addy Osmani has demonstrated how ServiceWorker can be used to cache the Shell of an app. When the DOM is modified on the client, it is updated in the cache. The next time that URL is requested, the ServiceWorker replies with html that is ready for use before the app has booted.
The other advantage regards lie-fi: when it seems the network is available, but not enough packets are getting through. ServiceWorkers can afford to have a near-imperceptible timeout, because they can serve immediately from cache and wait for the response to load (if ever).
Your consideration is invalid.
Service worker is designed to work like a proxy server that can especially handle some off-page operations like offline ability, push notification, background synchronization, etc. So in your case, you will gain no performance benefits by caching images with service worker over the traditional browser's cache approach.

Prevent recursive calls of XmlHttpRequest to server

I've been googling for hours for this issue, but did not find any solution.
I am currently working on this app, built on Meteor.
Now the scenario is, after the website is opened and all the assets have been loaded in browser, the browser constantly makes recursive xhr calls to server. These calls are made at the regular interval of 25 seconds.
This can be seen in the Network tab of browser console. See the Pending request of the last row in image.
I can't figure out from where it originates, and why it is invoked automatically even when the user is idle.
Now the question is, How can I disable these automatic requests? I want to invoke the requests manually, i.e. when the menu item is selected, etc.
Any help will be appriciated.
[UPDATE]
In response to the Jan Dvorak's comment:
When I type "e" in the search box, the the list of events which has name starting with letter "e" will be displayed.
The request goes with all valid parameters and the Payload like this:
["{\"msg\":\"sub\",\"id\":\"8ef5e419-c422-429a-907e-38b6e669a493\",\"name\":\"event_Coll_Search_by_PromoterName\",\"params\":[\"e\"]}"]
And this is the response, which is valid.
a["{\"msg\":\"data\",\"subs\":[\"8ef5e419-c422-429a-907e-38b6e669a493\"]}"]
The code for this action is posted here
But in the case of automatic recursive requests, the request goes without the payload and the response is just a letter "h", which is strange. Isn't it? How can I get rid of this.?
Meteor has a feature called
Live page updates.
Just write your templates. They automatically update when data in the database changes. No more boilerplate redraw code to write. Supports any templating language.
To support this feature, Meteor needs to do some server-client communication behind the scenes.
Traditionally, HTTP was created to fetch dead data. The client tells the server it needs something, and it gets something. There is no way for the server to tell the client it needs something. Later, it became needed to push some data to the client. Several alternatives came to existence:
polling:
The client makes periodic requests to the server. The server responds with new data or says "no data" immediately. It's easy to implement and doesn't use much resources. However, it's not exactly live. It can be used for a news ticker but it's not exactly good for a chat application.
If you increase the polling frequency, you improve the update rate, but the resource usage grows with the polling frequency, not with the data transfer rate. HTTP requests are not exactly cheap. One request per second from multiple clients at the same time could really hurt the server.
hanging requests:
The client makes a request to the server. If the server has data, it sends them. If the server doesn't have data, it doesn't respond until it does. The changes are picked up immediately, no data is transferred when it doesn't need to be. It does have a few drawbacks, though:
If a web proxy sees that the server is silent, it eventually cuts off the connection. This means that even if there is no data to send, the server needs to send a keep-alive response anyways to make the proxies (and the web browser) happy.
Hanging requests don't use up (much) bandwidth, but they do take up memory. Nowadays' servers can handle multiple concurrent TCP connections, so it's less of an issue than it was before. What does need to be considered is the amount of memory associated with the threads holding on to these requests - especially when the connections are tied to specific threads serving them.
Browsers have hard limits on the number of concurrent requests per domain and in total. Again, this is less of a concern now than it was before. Thus, it seems like a good idea to have one hanging request per session only.
Managing hanging requests feels kinda manual as you have to make a new request after each response. A TCP handshake takes some time as well, but we can live with a 300ms (at worst) refractory period.
Chunked response:
The client creates a hidden iFrame with a source corresponding to the data stream. The server responds with an HTTP response header immediately and leaves the connection open. To send a message, the server wraps it in a pair of <script></script> tags that the browser executes when it receives the closing tag. The upside is that there's no connection reopening but there is more overhead with each message. Moreover, this requires a callback in the global scope that the response calls.
Also, this cannot be used with cross-domain requests as cross-domain iFrame communication presents its own set of problems. The need to trust the server is also a challenge here.
Web Sockets:
These start as a normal HTTP connection but they don't actually follow the HTTP protocol later on. From the programming point of view, things are as simple as they can be. The API is a classic open/callback style on the client side and the server just pushes messages into an open socket. No need to reopen anything after each message.
There still needs to be an open connection, but it's not really an issue here with the browser limits out of the way. The browser knows the connection is going to be open for a while, so it doesn't need to apply the same limits as to normal requests.
These seem like the ideal solution, but there is one major issue: IE<10 doesn't know them. As long as IE8 is alive, web sockets cannot be relied upon. Also, the native Android browser and Opera mini are out as well (ref.).
Still, web sockets seem to be the way to go once IE8 (and IE9) finally dies.
What you see are hanging requests with the timeout of 25 seconds that are used to implement the live update feature. As I already said, the keep-alive message ("h") is used so that the browser doesn't think it's not going to get a response. "h" simply means "nothing happens".
Chrome supports web sockets, so Meteor could have used them with a fallback to long requests, but, frankly, hanging requests are not at all bad once you've got them implemented (sure, the browser connection limit still applies).

How to deal with a big set of pending requests

I want to implement web site that will display to user a notification about some event happened on server. My plan is:
to make an asynchronous request to the server (ASP.NET) which will have a 600 seconds time-out
if event occurs on the server in the time interval of these 600 seconds server will response with an event details
if event is not occurred the server then server will send an 'no event' response at the end of 600 seconds
JS upon receiving a feedback from server will process the response and send the next request.
The problem of the approach is that for a big amount of visitors web site will have a lot of 'pending' requests.
Questions:
Should I consider that as a problem? What is solution for that? Probably I should implement another approach?
Please advice, any feedback is welcome.
I don't know specifics about asp.net's handling of pending requests, but what you are describing is basically long-polling. It's tricky for a number of reasons, including but not limited to:
each pending request consumes a thread, and you'll need to store state on each of those threads
if you have enough connections (not necessarily all that many; see above), you'll need them to span multiple machines, and you then need to come up with an architecture to distribute endpoints across those machines, and make sure each incoming request goes to the right machine. If you're only broadcasting the same data to all your users, this becomes much easier.
proxies or ISPs or what-have-you may shut down your long-poll request. You'll need an architecture resilient to that.
Here's a question about long-polling in asp.net: How to do long-polling AJAX requests in ASP.NET MVC? It's probably a good place to start.
Also you could consider a 3rd-party service like pusher to handle these connections for you, or (disclaimer: I work on App Engine) App Engine's Channel API.
Surely you could make more frequent requests to the server that do not consume server resources for 10 whole minutes?
e.g. send an AJAX request every 60 seconds or so, and return whether or not any event has occurred. The downside is that it could take up to a minute for a user to see notification about some event, so if you need it more or less immediately, that is a problem.
If it does have to be immediate, it seems like looking into "long polling" with something like node.js might be a solution, though non-trivial to implement.

Categories

Resources