Service workers and page performance - javascript

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.

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.

Clear a PWA's cache periodically using javascript

I need all of the users of my application(desktop and tablet users) to start everyday with an empty cache.
Is there any way I can take advantage of service workers to achieve this?
Has anybody ever tried to do this? Or do you think there's a better way to run a schedule tasked on all the devices where my PWA is installed.
Thanks
Service worker cache super-cedes browser cache and honestly you should focus more on it than browser cache.
There is not a way to purge browser cache via the service worker or UI script for that matter. You have no control over that.
Even setting the Cache-Control header may not really matter. Browsers can be more aggressive as they deem necessary. Routers, load balancers, etc call get in the way as well.
If you are using service worker cache you can invalidate it any way you want. I have made some very sophisticated service workers, especially in recent months around invalidating cached assets in SW cache and indexedDB.
It is way more complex than I can share here LOL. There are numerous strategies you can employ, it all depends on what goals you have and what call the persona of your network addressable assets :)

Long-running process inside a Service Worker (or something similar)

I have a client-side JS app that uses IndexedDB to store its state. Works fine. However, it's kind of slow because I am frequently reading from and writing to IndexedDB so that the state does not become inconsistent when multiple tabs are open.
My idea was... put all DB access stuff inside a Service Worker, and then I can cache values there in memory without worrying that another tab might have altered the database.
That seems to work fine, except some parts of my application take a long time to run. I can communicate the status (like "X% done") from the Service Worker to my UI. But both Firefox and Chrome seem to kill the worker if it runs for more than 30 seconds, which is way too short for me.
Is there any way around this limitation? If not, any ideas for achieving something similar? A Shared Worker could do it I think, except browser support is poor and I don't anticipate that improving now with the momentum behind Service Workers.
The Google documentation on service workers tells us that using service workers as a memory cache is impossible:
It's terminated when not in use, and restarted when it's next needed, so you cannot rely on global state within a service worker's onfetch and onmessage handlers. If there is information that you need to persist and reuse across restarts, service workers do have access to the IndexedDB API.
My suggestion is to keep using service workers to persist data to the database, and use localStorage to create a shared cache between pages. The tab that is making the change is then responsible for both updating the cache in localStorage and persisting to IndexedDB through the service worker.
I ended up using a Shared Worker. In browsers that don't support Shared Workers, such as Edge and Safari, I fall back to a Web Worker and some hacky code to only let you open the app in one tab at a time.
Since 90% of my users are on Firefox or Chrome anyway, I figure it's not a huge loss.
I also wrote a library to (amongst other things) normalize the APIs used in Shared Workers and Web Workers, so I have the exact same code running in both scenarios, the only difference is whether the worker is initialized with Worker or SharedWorker.
As you said yourself SharedWorkers seems to be exactly what you need.
I'm not sure why you think the momentum behind implementing ServiceWorkers prevent browsers from supporting SharedWorkers. They seem to be two different kind of beasts.
As far as I understand ServiceWorkers should be used as a proxy for your requests when your application is offline and heavy stuff should be done in WebWorkers and SharedWorkers
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker

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

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

How to load a javascript file from the best source

I have a few web servers in different locations and would like to load my javascript files from the fastest (nearest??) server. For example in Location A, I would expect the users to get their files from servers in that Location, but users from Location B would get their files from other servers, hopefully servers from location B, but that is not necessary.
I have found how to load javascript files conditionally, and I think that is a good start. I just need a way to find which is the best source(faster response).
Thanks,
Just use a CDN if you want that minimal performance advantage. This would differ a few milliseconds.
There is a list of CDN on http://jquery.com/download/#using-jquery-with-a-cdn
The only advantage of using a CDN is that the user may have downloaded the jQuery library earlier from another website, so the jQuery library is reused from it's cache.
If you are encountering performance problems, try profiling the website and check the ammount of time that a resource takes to run or load.
This isn't really a problem the client should solve. You should put your server behind a proxy that balances the load. If the proxy's bandwidth isn't enough, then I think you're out of luck. A quick and dirty solution is to do a Math.random() in the client side and choose the server based on that. It should balance the load pretty evenly.
If you were to measure the response time from the mirror servers, you would just introduce more load. Lets say, we have a way to determine the response time. You would either request the file from all servers, meaning you just made everything worse, or you would wait for server1, and if that didn't respond in time, you would move to server2. But by doing this you introduced load to server1.
Also if you were to ping the server, that isn't a real indicator if the available performance of that server. The server might be able to respond fast as the response is short and requires no real IO, but if you were to request a file that would mean possibly reading from the disk.

Categories

Resources