My honest impression is that the entire "PWAs are good" are basically the crowd that make cheap apps discovering a way to sell to Mac users without having to actually make quality software. Any time I encounter a PWA or a chrome wrapper "native" app it's just another chance to experience an app that can't do basic things like "find" correctly.
The entire argument for PWAs is "it's cheaper". I have not once seen a "it results in a better UX or app".
Not necessarily cheaper to make but your revenue isn’t cut by 30%.
Also your app can run almost instantly by visiting a link. App Clips and Instant Apps don’t really cut the mustard unless your app is tiny
Installing to the home screen is not the reason they never took off.
It's because the user experience on them is terrible compared to native. Really is as simple as that.
… because there’s perverse incentives to keep it that way
It was not designed for highly dynamic, fluid, responsive experiences.
> specific performance tradeoffs
But you don’t specify.
Android is built upon the JVM which is affected by GC pauses much the same as JavaScript, but the performance issues are solvable in the browser as much as they have been in the ‘native’ Android domain
I'm also not sure why I'd have to list the tradeoffs on a forum of developers.
They're self-evident.
HTML and the DOM are always going to be a less efficient representation of an interface than a component tree. CSS is always going to be a less efficient manor of appearance specification than direct properties on a component object. JavaScript is always going to be less efficient than something compiled down to machine language.
Each adds several layers of abstraction, processing and adaptions that add overhead. That's their whole point.
It's not exactly something you can "debate".
> HTML and the DOM are always going to be a less efficient representation of an interface than a component tree
Is the DOM – from which is derived from HTML – not also a component tree? Is it a graph or some other topology I'm not aware of? When you specify a design in Interface Builder, Android xml, or even the DOM-differ-like SwiftUI + Jetpack Compose how is the topology different? Check a DOM object, it's a node with children.
> CSS is always going to be a less efficient manor of appearance specification than direct properties on a component object.
Property inheritance is definitely a thing on both Android and iOS. I'm sure you could confect especially non-performant CSS, but at large it isn't taking up great deal of compute. I've definitely seen weird constraint issues on Interface Builder cause glitches and pauses (and even crashes) on iOS.
> JavaScript is always going to be less efficient than something compiled down to machine language
Javascript can be compiled down to machine language, using the JIT. Similarly Android is compiled down to Dalvik/Java-like byte code and run on a JIT. Is Android not native? Or is it some No True Scotsman kind of thing?
> I've been a mobile developer for 10 years, a web developer for 2-3 years, and I've done perf with C++/Asm for years of my career, so know that I'm not coming from a place of naivete on either performance or mobile/web development.
with this:
> Is the DOM – from which is derived from HTML – not also a component tree? Is it a graph or some other topology I'm not aware of? When you specify a design in Interface Builder, Android xml, or even the DOM-differ-like SwiftUI + Jetpack Compose how is the topology different? Check a DOM object, it's a node with children.
Would you like to point out where I'm mistaken? Or are you just feigning superiority?
DOM objects can have exactly one parent, many children, and cannot have cycles (i.e, no parent can be itself or a child). It's very specifically a tree[0] of components. I'll take the L here if I can learn something from you. So tell me, with accuracy, how HTML/DOM is not a component tree? And then extra points as to why this different data structure is inherently less performant.
I'd recommend reading through WebCore, from the WebKit project, as its some of the most readable CPP you'll find, and should give a sense of why that implication is naive:
> converting that markup into a tree
The web is indeed dynamic. It means any cache-misses for webpages will require re-parsing. Could be substantial compute depending on the size of the page, but not necessarily – the vast majority of the delay of a webpage is network. But we're talking a web app here. If it is something visited often (as one would use an app), it's a cache-hit, if it's occasional usage, it's analogous to downloading an app again, but much faster and without having to jump to the app store to do it.
> which in turn may/would have a component tree attached
Read my earlier comment. Component trees are not a point of difference here.
> maintaining state between the DOM's tree
Once again, not a point of difference. DOM manipulation is component tree manipulation, much the same as what's happening under the hood in SwiftUI and Jetpack Compose.
> to an interpreted runtime
Once again, if you're not using an app often, there's a cache-miss and the code will need to be re-parsed, but that's the trivial 'download cost' of the app. Once parsed it's JITable byte code much like Dalvik on Android.
> I'd recommend reading through WebCore
That's cute. Given this whole thread I'd wager you've never read it before, let alone grokked it any of it. You're probably capable of doing so, and you're welcome to, but I'll make no pretense of having read it or intending to.
Caching and execution of dynamic JS was a difficult problem, but one that has received a lot of attention. Similarly caching of dynamic HTML and CSS. These performance problems are fortunately the purview of specialized developers building one of the 3 browser engines in popular use and complexity well abstracted from the developer.
There is one main drawback, which you haven't mentioned yet, that is memory and storage. But once again, because it's cached, it's very easy to 'eject' a web app from storage (e.g. using an LRU policy).
But of course the elephant in the room is that many popular 'native' apps are just Ionic/Electron ports[0], because people gave up waiting for PWAs to be supported fully by mobile OS and browser engine teams. I've used 1Password, Spotify, Slack, Signal, etc. built on HTML/CSS/JS and I don't experience jank, because the performance problems have been solved. You might retort, "But they aren't dynamically loaded", to which I'd point you to back to the concept of caching.
[0] https://en.wikipedia.org/wiki/List_of_software_using_Electro...
And with that, I'm done here.
> Can you make an argument as to why a browser can't provide a native-like experience?
And behold, I explained why.
Every abstraction you layer onto a stack has a performance tradeoff.
You essentially rebutted by saying "we can make things faster" and ... no one said we couldn't.
Your second rebuttal is essentially, "Well, things are fast enough for me!" Which ... OK.
I said they are fast now for the reasons specified.
> "Well, things are fast enough for me!" Which ... OK.
They're 60+ fps. Fast enough for everybody.
This reflects trends in software development. Cheap and easy for developer. Poor user experience.
You see, the goalposts on what "PWA-specific features" are are moved all the time. Because everyone selects their own set of features to wave about as "the one true support for PWAs".
Meanwhile Android has 70% of marketshare in the world, and none of the imagined PWA restrictions. And we've yet to see a single amazing PWA there that Apple is purportedly stopping from happening on iOS.
They shipped a lot of features in Safari over the years, including many that that landed before Chrome and Firefox's implementations, and in general, Safari has remained the fastest, most power-efficient browser on macOS. But PWA-specific features weren't high on the list. Users didn't want them; developers wanted them, and Apple has rarely prioritized what Developers want over what their Users want – with both being second to what Apple wants.