Please don't convert your website to PWA before thinking if it really adds an value to your visitors first. Some sites are just great as they're now. I understand you spent time "pimping up" your website, but No I don't want to receive push notification from your site, or ability to visit your website offline. Maybe I'm visiting your website for just single article and you'll never see me again. It reminds me AMP situation. Those who stepped into hype train, are now those whose starting to realise that maybe it wasn't such a great idea at first place.
> No I don't want to receive push notification from your site...
A PWA does not equal push notifications. Those are completely optional and should of course only be added where that makes sense. And even then, you'd have to agree to receiving them first.
> ...or ability to visit your website offline
Fine, you don't have to. In that case, the service worker just improves page speed and reduces data usage.
browser already do caching well, but you have to setup your server to sent correct headers and it's kind of difficult (unpractical) to set different caching policy for different kind of files if you're hosting many different sites, or you're on shared hosting. With service worker you can have more granular control over caching. But again, you really have to know, what are you doing. For regular website using service worker to improve caching is IMO overkill and also there is small chance, you'll make it unwillingly worse.
> it's kind of difficult (unpractical) to set different caching policy for different kind of files if you're hosting many different sites, or you're on shared hosting
No it's not. In Apache and Nginx (and I assume any other half decent web server) it is very easy to specify different cache times for each file extension. Same on shared hosting (.htaccess)
apache yes, but what about nginx? And there are many other ways, how to host your site (Amazon S3,...).
Also by unpractical I mean you have to have access to the server (ssh...). IMO it should be more concern of an app then server. But I'm not advocate for service worker for static resource caching (for websites).
Those were just examples. PWA is short for progressive web application. And this article title is "Turning your website into PWA". My point is, that if your site is just regular website not an application, staying conservative about implementing features is better, then implementing them recklessly, just for temporary page rank boost, or to show how cool programmer your are.
EDIT: still talking about regular websites? First visit or repeated visit? Most website already can take advantage of plain browser caching and service worker is IMO hard to sell here.
Repeat visit, of course :) The service worker can't do anything before it's installed (during the first visit). The browsers' network cache is great, but IIUC the browser still performs those 'if-modified-since' requests, doesn't it? Additionally, depending on your server setup and CDN, some assets may have a short max-age value, meaning they're reloaded more often than needed. With service worker, the website can create its own cache and have full control over it. In other words, the site can guarantee that its assets will be loaded directly from the browser's memory.
This is clearly overengineering if one has to write and maintain a service worker just to be able to display a static site offline. How to debug it? How to see if any of your visitors cannot load site because of error in a service worker? How to decide which pages to preload for offline reading?
Also a service worker would add additional process in Chrome and require 30-40 Mb of RAM. I don't want service workers in my browser.
Well, web standards have always been this broken and illogical as long as I rememeber.
> How to see if any of your visitors cannot load site because of error in a service worker?
The service worker fetch event is a promise, so you can catch any errors encountered and tell the client to go fetch the remote version instead. You can then do whatever analytics stuff you want with the error.
> How to decide which pages to preload for offline reading?
Well, who knows. But it's flexible enough to let you decide yourself - the last attempt, AppCache, forced you to decide upfront. With a service worker you could in theory use a user's browsing history to know what pages they are likely to look at. Or you can actually create responses manually in the worker, so you can dynamically generate an entire page locally on the device. It's very powerful.
> Also a service worker would add additional process in Chrome and require 30-40 Mb of RAM
This part I can't argue with. I mean, Chrome already uses a different process for every tab, but more resources is more resources.
I don't see service workers as over engineering, I see them as a low level API. We just need some abstractions.
There is still a problem that some sites will have a service worker and some will not. Maybe it would make more sense to allow the user to pick what they want to cache for offline reading.
> The service worker fetch event is a promise,
By the way promises is another poorly designed technology: they catch unhandled errors and do not report them in any standard way [1].
> There is still a problem that some sites will have a service worker and some will not.
Why is that a problem?
> By the way promises is another poorly designed technology: they catch unhandled errors and do not report them in any standard way
If you're using promises there is really no reason to not be handling your errors. Catching unhandled errors is by design and it works great. It's absolutely trivial to do.
And, as the SO post you've linked to points out, you can catch unhandled promise errors using window.onunhandledrejection. It's not like it's that dramatically different to window.onerror. Promises might not be perfect, but they're better than JS callback hell in absolutely every way.
By the way I have tried to use promises in PHP (they are almost the same as JS promises) and had the same problem with promises catching all exceptions and reporting nothing. I am thinking now about writing my own version of promises because nobody seems to understand how to handle exceptions and unhandled rejections correctly.
> Catching unhandled errors is by design and it works great.
I don't think that it's great because by default I would prefer to terminate the application if there is an unhandled error or rejection. This is called "fail fast" principle. What promises developers suggest is to continue running the application even if it's broken.
Tearing down an entire application immediately due to an asynchronous exception has the possibility to leave the system in a deadlock or worse. It's a bad idea in any asynchronous environment.
JS isn't today truly asynchronous in most usage today, but they are planning for that future (present if you count Service Workers and Node/Electron).
What you are suggesting (preventing errors from crashing application) only makes discovering errors more difficult. For example, application might look like it is working ok, but some of requests do not return any response or return invalid data - because an exception was ignored.
Try googling "fail fast" if you want to see more reasons to use this principle.
> Tearing down an entire application immediately due to an asynchronous exception has the possibility to leave the system in a deadlock or worse.
It should not. Because application can crash anyway - for example, if there is memory access violation or out-of-memory error. And synchronous applications crash on uncaught exception, I don't see why asynchronous applications should not.
Fail fast is also a terrible user experience: why did my app just disappear, did I do something wrong? It implies blame to users that may not be at fault.
Sure, fail fast is very useful in debuggers to help a developer find and fix problems. But this is why we have debuggers. Debuggers are a terrible user experience, we don't need to force every user to live in a debugger and decide themselves which errors matter.
Not every exception is "fatal" and "might look like it is working ok" is often good enough in the pragmatic real world where you can't control everything.
Also, just because you've never accidentally caused a machine to BSOD on a deadlock or catch fire from an improper halt in a "fast fail" of multi-threaded code, that just means you are one of the lucky ones. There are disastrous consequences to bad multi-threaded code during "fail fast" teardowns of threads not privy/cause to the error. There are enough nightmare scenarios to keep a multi-threaded programmer up at night.
I appreciate your concern that developers sometimes ignore errors they should fix instead or handle more appropriately. "Fail fast" in a debugger works to help that. "Fail fast" in day-to-day operation isn't the right solution, at the very least for making users possibly hate you because you'll never properly handle 100% of exceptions.
I have worked with code (in PHP) that didn't use "fail fast" approach and didn't even log most warnings and notices. App didn't crash but sometimes randomly returned invalid results. Of course, nobody fixed this because after reloading the page the error could be gone. If you ignore errors or warning you just get low quality code as a result. Maybe this code will corrupt your database content, who knows. It is safer to stop the code if something seems wrong.
Also I remember reading somewhere that the earlier you find the error the cheaper it is to fix it.
> why did my app just disappear, did I do something wrong?
Usually operating system reports that there was an error in the application. If the application crashes often, the users will complain to developers and they will fix it.
> Debuggers are a terrible user experience, we don't need to force every user to live in a debugger
You should test your app properly before releasing it.
> There are disastrous consequences to bad multi-threaded code during "fail fast" teardowns of threads not privy/cause to the error.
I cannot agree with this. Usually the OS releases all locks, closes all files, frees memory when the process terminates. I don't see what can go wrong here and how you can get a deadlock because some process has terminated. Also if you use locking you should add some kind of timeout. For example, MySQL has lock timeouts and can even detect and fix deadlocks.
> "Fail fast" in day-to-day operation isn't the right solution, at the very least for making users possibly hate you because you'll never properly handle 100% of exceptions
The users will probably hate you more if the app will silently hang or show incorrect data.
> And, as the SO post you've linked to points out, you can catch unhandled promise errors using window.onunhandledrejection. It's not like it's that dramatically different to window.onerror.
Why make a new non-standart event instead of just throwing an error and handling it with default error handler? That is poor design - because initially there was no reporting of unhandled errors at all and only later a workaround was added.
`window.onunhandledrejection` is a part of the spec, it simply took a bit for browsers to catch up to it.
It's a different handler because an application may need to know the difference between a synchronous error and an asynchronous error and handle them (dramatically) different.
If there is a need to distinguish between different kind of errors then it can be done by checking error prototype (if (error instanceof AsyncError) { ... }). There was no need to introduce a new event.
I think the reason is because some developers have a kind of exception-phobia and they prefer to hide errors (make developer check for them explicitly) rather than let them bubble up.
I see this in other platforms too. For example, in .NET if a background thread crashes because of unhandled exception then nothing happens to the main thread, no error is reported. The developer must check for an error and of course most developers won't care about this.
Another example is how error reporting is done in a browser. JS errors are never shown to the user so if a rich JS app has an error the user won't know about it, the app will just stop working or show invalid data.
Browsers have a long backwards compatibility story to deal with and the interplay of synchronous errors and the synchronous error event is a part of that. Just because you don't see a need to introduce a new event doesn't mean bright minds didn't think about it.
PWA is very slick for making complex client-side web applications work and feel much more like native mobile applications, in terms of faster launch, off-line, etc. (And by the way, the machinery to make them work is getting quite nicely integrated in the box with Angular for example - I expect the same for other SPA libraries coming soon also).
But I am somewhat skeptical of the implications beyond SPAs, which is that, across the entire Internet, basically every static website in the world should be converted to a PWA for an optimal mobile experience. Doesn't that seem backwards? Shouldn't mobile browsers have a way to "just work" and give a great experience for static websites, rather than changing all the sites? Shouldn't we only need something like PWA for rich SPAs?
I agree to an extent, but it's important to remember that Progressive Web Apps are really just a branding exercise for a bunch of different technologies, and you don't have to implement them all.
A news site might see huge value in implementing push notifications, whereas a shopping site might not. Messaging sites may see huge value in background sync, but it will be of little value to others. So on, and so forth.
My main complaint is that the biggest win for PWAs is simple caching - you can explicitly choose which resources to add to a cache instead of relying on the normal browser cache. This becomes necessary on mobile because the browser cache is very small and is emptied far too often - I'd rather them solve that problem before forcing everyone to make a service worker just to ensure their CSS and JS is cached successfully.
I would argue that, while not every site should have to be converted to a PWA to work properly, every site can benefit from it. If a website is not a complex SPA, why should it not be fast, secure or offline-accessible?
HTTPS or Service Worker caching is not something a mobile browser can do for you by default.
It seems to me that a lot of the technology making up PWA has been bundled with a PWA philosophy that has made it difficult for folks coming from a progressive enhancement background to understand how it can be applied. Too many people make it seem like an all-or-nothing deal, or couple learning these technologies with other technology that's not an essential. In reality you can incrementally add pieces to your approach for new site, or improve an old site.
Or you could just serve a small website without scripts or huge images that doesn't need to be progressive because it could be viewed just as well on some 100Mhz Pentium I class computer over a 56k connection.
What is the point of this comment? If you want to create a tiny static web page for which the benefits of a service worker are nominal, then do it and stop worrying about it. That's not the purpose of service workers anyways.
Wait, you need at least a Pentium III, the one that was "designed for the Internet"[0].
> The Pentium III processor's Internet Streaming SIMD Extensions Instruction Set has been a hit with software developers resulting in numerous optimized Web sites and software applications available today.
Maybe my users want to do more things with their computer than just display a website. And maybe they don't want my website to prevent their processor from entering a sleep state because it does unnecessary background work. Maybe my users pay for their data, or maybe they have a poor connection.
> And maybe they don't want my website to prevent their processor from entering a sleep state because it does unnecessary background work.
Good news is that a service worker can't do that. It gets automatically shut down after a short period of time. It will be woken up again in response to push notifications, which you must request permission for, or in response to a new user event.
> Maybe my users pay for their data, or maybe they have a poor connection.
Which is why providing greater offline capability is a good thing, not a bad thing.
A decent primer which wisely handles the important things first: namely, misconceptions around what it is & what's required.
"Application" in PWA is best thought of as indicating the user experience on a mobile, with the ability to add to homescreen without downloading via an app store, and offline capabilities. Where PWA shines is website > AMP > PWA. See https://www.google.com/search?q=myntra+kurtis on your mobile for a great example of this transition.
Illustrated with an image that includes a giant bar with "ADD TO HOME SCREEN" on it. I already know how to do that on my phone. If I go to a page with a bar like that, I'm closing the page. I'm sure I'm not alone.
I believe that's a Chrome feature, not a specific website feature. If you have a manifest and it's https, Chrome will ask if you want to add to home screen. Although, I think they only ask once.
Is it impossible for websites to use my horizontal space? I don't like having a tiny bar in the middle when I have 300 unused pixels either side of the text, this phone centric internet is really annoying on desktop.
While your horizontal space can be very useful for code and server logs, the ideal measure for reading text is around 66 characters per line[0], spaces included.
Make it too long and you may have trouble to find the next line. Make it too short and your eyes will suffer from traveling back too often.
I'm pretty sure this is because there's a critical limit on how wide a column of text can be before your eye won't snap back to the next line as easily. The thing I love about the phone centric web is that I don't have to have my browser full screen (as you say, it just wastes space).
As I understand, progressive here means that it will work as an ordinary website even if the extra features like Service Workers aren't supported by the browser.
For me progressive should mean, that features (like adding to home screen, push notifications...) reveals progressively. Visitor should show some engagement, before PWA start to offering those features. Definitely not on first visit. It's very trendy nowadays, but extremely annoying to cancel all those feature request popups. "Do you want to receive push notifications?", "Please install our app for better experience", "Add app to homescreen" ... That's not web I like. And yes, I do realise it's far from original definition.
I think that it would be better to remove popups and only show an icon in the address bar so the user can click it and grant necessary permissions. My version of Chromium shows an icon when a site wants to install a service worker.
I was under the impression that the Progressive part of PWA meant Progressive Enhancement.
I have a PWA that creates html/css in the build process.
If JS is enabled, it acts as an SPA.
If JS is disabled, it's a simple static site.
If ServiceWorker can be used, caches the html/css I built which both the SPA and static site versions can use.
If no SW, then fallback to AppCache/LocalStorage/etc.
The hardest part was finding a CSS framework that doesn't use JS and still can do menus/etc nicely.