Clear a PWA's cache periodically using javascript - 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 :)

Related

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

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.

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.

Versioning in device/server development

I am working on device applications, that we will deploy some minimum device specific code to the device, and this component will dynamically load the rest of resources (javascript, images, etc) from our backend server. That way we can upgrade the app more often without depending too much on the device upgrade. In a way, this is similar to some iphone developers who want to avoid the app approval cycle with faster upgrades.
The code in device should be able to detect new upgrades on the server code, but only to a point, when we need to upgrade the device code as well, so we can support phased roll-out (upgrade 10% of devices at a time, etc).
I am sure some folks have already done this. Could you share your thinking and best practices on this?
One way would be for the application to have a polling process that asks a server if there is a new version of a particular resource.
The server then has complete control over who gets the upgrades and who doesn't (part of the "phone-home" could include the current version), and that would allow you to enforce the "only X% of clients get upgraded" capabilities. You may also want to include the ability for things to get "downgraded" so that you can roll back if you see too many errors in the first 10%.
This is essentially what web browsers do when they have a resource in the cache but it may have been expired. They say "Hey, Server, I have this resource that I got from you at XYZ date. If it's changed, give me a new one, if not, let me know." and the server either sends back a "Hasn't Changed" response, or a "Here's the new one" response.

How to create temporary files on the client machine, from Web Application?

I am creating a Web Application using JSP, Struts, EJB and Servlets. The Application is a combined CRM and Accounting Package so the Database size is very huge. So, in order to make Execution faster, I want prevent round trips to the Database.
For that purpose, what I want to do is create some temporary XML files on the client Machine and use them whenever required. How can I do this, as Javascript do not permits me to do so. Is there any way of doing this? Or, is there any other solution which I can adopt in order to make my application Faster?
You do not have unfettered access to the client file system to create a temporary file on the client. The browser sandbox prevents this for very good reasons.
What you can do, perhaps, is make some creative use of caching in the browser. jQuery's data method is an example of this. TIBCO General Interface makes extensive use of a browser cache for XML data. Their code is open source and you could take a look to see how they've implemented their browser cache.
If the database is large and you are attempting to store large files, the browser is likely not going to be a great place for that data. If, however, the information you want to store is fairly small, using an in-browser cache may accomplish what you'd like.
You should be caching on the web server.
As you've no doubt realised by now, there is a very limited set of things you can do on the client machine from a web app (eg, write cookie).
You can make your application use the browser plugin Google Gears, that allows you a real clientside storage.
Apart from that, remember, there is a huge overhead for every single request, if needed you can easily stack a few 100 kB in one response, but far away users might only be able to execute a few requests per second. Try to keep the number of requests down, even if it means adding overhead in form of more data.
#justkt Actually, there is no good reason to not allow a web application to store data. Indeed HTML5 specifications include a database similar to the one offered by Google Gears, browser support is just a bit too sporadic for relying on that feature.
If you absolutely want to cache it on the client, you can create the file on your server and make your web app retrieve it. This way the browser will fetch it and keep it on the client cache.
But keep in mind that this could be a pain for the client if the file is large enough.

Categories

Resources