Progressive Web Apps on iOS might be in trouble

IMPORTANT: iOS 11.3 final version is now published. Check my updated article on the topic: Progressive Web Apps on iOS are here

After the surprise yesterday from a tweet from Ricky Mondello and then the Safari 11.1 beta Release Notes stating that Web App Manifest and Service Workers are implemented which means multi-platform PWAs are now possible, it’s now time to come back to the real world and see what’s what we have.

Update 8-Feb: Beta 2 is out and the WebKit blog has published an article on how Service Workers work on its platform. This post is updated with this information.

Update 20-Feb: Beta 3 is out. This post is now updated for this version.

Update 7-Mar: Beta 4 is out. This post is now updated for this version.

Testing is not easy — better from beta 3

Testing these new additions on iOS is not straightforward because the Developer Tools on Safari won’t let you see the Service Workers on iOS yet using the Service Workers menu. However, when you connect an iOS remote inspection session, you will find two sessions with the same name, of those is the Service Worker session. It’s still a limited devtool for Service Workers but it’s a start. You will need Safari Technology Preview installed in your macOS computer for Service Worker debugging.

With Safari Technology Preview you can see two airhorner.com inspectable sessions per platform, Safari and Web (home screen PWAs). One session is the normal web session and the other one is the Service Worker. Apple: we need a flag for the SW :)

If you published a PWA or are about to release one, you must pay attention to the user experience and the issues you might have on iOS.

18 months ago (one and a half years already!?) I published “Don’t use iOS meta tags irresponsibly in your Progressive Web Apps.” Several companies such as Twitter and Flipkart took note at that time of these problems and remove the iOS meta tags or solved the issues (You are welcome for the free consulting ☺️).

At that time the problem was that some companies were opting in through Apple meta tags for home screen support for iOS without even testing and recognizing the differences between Android’s PWAs and iOS.

I’m sorry to confirm that most problems are the same that I stated 18 months ago, with one big difference: now you don’t need to opt-in into iOS; iOS will add support for Web App Manifest, so your PWA will be an iOS PWA automatically. But Apple didn’t mimic the same behavior as in Android which means: Cupertino, we have a problem.

A completely different Service Workers’ story

This section was added on Feb, 8th.

Apple followed the Service Worker API, but it creates an entirely different story of what it is and what we can do with it in the future. The main differences appear when Apple says:

“To keep only the stored information that is useful to the user, WebKit will remove unused service worker registrations after a period of a few weeks. Caches that do not get opened after a few weeks will also be removed. Web Applications must be resilient to any individual cache, cache entry or service worker being removed.”

https://webkit.org/blog/8090/workers-at-your-service/

That is a huge change! At Chrome, Firefox, Samsung Internet, and other browsers, a Service Worker registration is not going to be unregistered automatically, and we can rely on being there in the future. That’s why an installed PWA will be able to work offline in the future. But with Apple’s idea of a service worker, there is no guarantee that the service worker or the cache will be available in the future. It might be if the user comes back to the web app within “a few weeks.” I know, the web app should work anyway while online, but we can’t guarantee one of the key concepts of PWAs: offline access.

While it seems fair from a browser’s point of view, I don’t see it as fair for PWAs in the home screen where the user expects the app to be there.

⚠️ In Apple’s world after “a few weeks”, the PWA will just load from scratch from the server registering a new instance of a service worker and caching the files again. This is a huge deal for Progressive Web Apps, if the user installs an icon, in a few weeks it won’t be available offline and the user will end up with a full screen “there is no internet” message for the installed app.

Also, Apple’s vision limits the future of other APIs on top of Service Workers, such as Background Sync or Web Push that needs the service worker registration to stay there for a while.

There is no event or other way to know that your service worker was unregistered and that the cache storage was erased.

Also, at the same time, Apple is officially deprecating AppCache. It’s still working with a console warning. The only problem is that AppCache life cycle will stay there as the Cache Storage on other browsers, but not with Apple’s idea of the cache. So, AppCache is being deprecated and replaced with something that can not offer the same behavior.

On the bright side of the story, at least we have a definition of what to expect from a Service Worker and also about the available space to store responses in the Cache Storage. It’s going to be up to 50 MiB per partition. MiB? It’s a mebibyte, and 50 of them are around 52.5Mb. Partition? A partition is a new concept for Service Workers and it has to do with iframes. If there is no cross-domain iframes in your web app, a partition if just an origin (your domain and port). For privacy reasons, Apple went further with the Service Worker specification, and creates a new partition (some kind of a new origin) when a service worker is registered from a cross-origin iframe. That Service Worker will be responsible for requests coming from clients within the same partition (combination of top origin and frame origin) only.

I don’t think this different vision of what a Service Worker should be is new. There were several discussions in the past between the Safari team and the Chrome team (I was involved in some of them on Twitter after I published this article two years ago) and I think this is just another chapter of the same discussion. Apple wasn’t involved in the discussion of what the replacement of AppCache needs to be and here we have the result: different implementations.

Update on beta 4: This was available from beta 3, but I missed it in this post. A PWA in the home screen shares the Service Worker registration with Safari. However, it creates a different instance of it; therefore you might end up with two instances of the same service worker running at the same time. If you follow Service Workers design patterns you shouldn’t rely on global variables inside this context so it shouldn’t be a big problem.

Installed icon but online only — solved from Beta 3

Up to beta 2: If you install your PWA on the Home Screen, Service Workers are there, it’s being registered but they are not working (the SW doesn’t take the Web App as a client) so don’t expect an offline experience in this first beta. But I think this is due to a bug that should be solved in future betas.

Update 20-Feb: On beta 3 this problem was solved, so home-screen PWAs now can work offline. However, if the user is in Airplane Mode, Safari shows the OS dialog asking the user to connect to WiFi, even if all the requests were managed by the Service Worker.

Even if the PWA is rendered properly by a Service Worker, Safari shows this dialog after opening a PWA from the home screen with airplane mode

PWAs: attack of the clones

Service Workers API is available on HTTPS at Safari, the Web View (that means, Chrome, Firefox, and Facebook In-App browsers), Apps added to the Home Screen (Web.app) and Safari View Controller (such as when you click on a link on Twitter on iOS).

It sounds good, right? Well, there is a significant issue here: on Safari and on each app’s Web view which means the user might end with several copies of all the files for the PWA on the same device.

Update beta 3: Safari View Controller (for example, browsing within Twitter) and home screen web apps share the same Cache Storage and Service Worker registration with Safari’s tab, but each mode gets a new Service Worker instance.

You might be thinking: Hey, Max, the same happens on Android and different browsers (Chrome, Firefox, Opera, Samsung Internet, UC Web). Well, you are right, but it’s a different use case. On Android, OS’ web views don’t have Service Workers support and PWAs on the home screen share the same SW and cache of the browser who owns that icon. Also, loading the same web apps on different browsers on the same device doesn’t seem to be a typical use case.

Now, let’s say you are an iOS user and you typically use a PWA, such as Twitter Lite. When you explicitly want to use it, you open your (pseudo)browser, such as Chrome, Edge or Firefox on iOS. You get one copy of the app. Because on iOS you can’t change the default browser if you receive a link on Mail to a tweet, Safari will open, and a second copy of the app will be “installed”. If you add it to the Home Screen as well fortunately, the same second copy of the app is there. Done? Not yet. If you use Facebook or some newspapers apps among other apps that offer you In-App browsing experiences, when you click on a link to a tweet or a Twitter account, you will have another copy per app!