The Reports of HTML’s Death Have Been Greatly Exaggerated…?


Yesterday’s post titled “Android Instant Apps / The Slow, Inexorable Death of HTML” surprisingly accumulated some 35,000 or so uniques in a few hours. It has yielded feedback containing recurring sentiments that are worth addressing.

it is weird the article trying to sell the idea that apps are better posted XKCD images stating otherwise

While there are situations where a native app can certainly do things that a web app can’t, and there are some things it can simply do better, the prior entry wasn’t trying to “sell” the idea that apps are inherently better (and I have advocated the opposite on here and professionally for years where the situation merits). It was simply an observation of Google’s recent initiative, and what the likely outcome will be.

Which segues to another sentiment-

The reverse is happening. Hybrid apps are growing in number. CSS/JS is becoming slicker than ever.

The web is already a universal platform, so why the ████ would you code a little bit of Java for Android instead of writing it once for everything?

In the prior entry I mentioned that some mobile websites are growing worse. The cause of this decline isn’t that HTML5/JS/CSS or the related stack is somehow rusting. Instead it’s that many of these sites are so committed to getting you into their native app that they’ll sabotage their web property for the cause.

No, I don’t want to install your app. Seriously.

Add that the mobile web has seen a huge upsurge in advertising dark patterns. The sort of nonsense that has mostly disappeared from the desktop web, courtesy of the nuclear threat of ad blockers. Given that many on the mobile web don’t utilize these tools, the domain is rife with endless redirects, popovers, the intentionally delayed page re-flows to encourage errant clicks (a strategy that is purely self-destructive in the longer term, as every user will simply hit back, undermining the CPC), overriding swipe behaviors, making all background space an ad click, and so on.

The technology of the mobile web is top notch, but the implementation is an absolute garbage dump across many web properties.

So you have an endless list of web properties that desperately want you to install their app (which they already developed, often in duplicate, triplicate…this isn’t a new thing), and who are fully willing to make your web experience miserable. Now offer them the ability to essentially force parts of that app on the user.

The uptake rate is going to be incredibly high. It is going to become prevalent. And with it, the treatment of the remaining mobile webfugees is going to grow worse.

On Stickiness

I think it’s pretty cool to see a post get moderate success, and enjoy the exposure. One of the trends that has changed in the world of the web, though, is in the reduced stickiness of visitors.

A decade or so ago, getting a front page on Slashdot — I managed it a few times in its hey-day — would yield visitors who would browse around the site often for hours on end, subscribe to the RSS feed, etc. It was a very sticky success, and the benefits echoed long after the initial exposure died down. A part of the reason is that there simply wasn’t a lot of content, so you couldn’t just refresh Slashdot and browse to the next 10 stories while avoiding work.

Having a few HN and Reddit success stories over the past while I’ve noticed a very different pattern. People pop on and read a piece, their time on site equaling the time to read to the end, and then they leave. I would say less than 0.5% look at any other page.

There is no stickiness. When the exposure dies down, it’s as if it didn’t happen at all.

Observing my own uses, this is exactly how I use the web now: I jump to various programming forums, visiting the various papers and entries and posts, and then I click back. I never really notice the author, I don’t bookmark their site, and I don’t subscribe to their feed. The rationale is that when they have another interesting post, maybe it’ll appear on the sites I visit.

This is just the new norm. It’s not good or bad, but it’s the way we utilize a constant flow of information. The group will select and filter for us.

While that’s a not very interesting observation, I should justify those paragraphs: I believe this is the cause of both the growing utilization of dark patterns on the web (essentially you’re to be exploited as much as possible during the brief moment they have your attention, and the truth is you probably won’t even remember the site that tricked you into clicking six ads and sent you on a vicious loop of redirects), and the desperation to install their app where they think they’ll gain a more permanent space in your digital world.

Android Instant Apps / The Slow, Inexorable Death of HTML

Android Instant Apps were announced at the recent Google I/O. Based upon available information1, Instant Apps offer the ability for websites to instead transparently open as a specific activity/context in an Android App, the device downloading the relevant app modules (e.g. the specific fragments and activities necessary for a need) on demand, modularized for only what the context needs.

The querystring app execution functionality already exists in Android. If you have the IMDB app, for instance, and open an IMDB URL, you will find yourself in the native app, often without prompting: from the Google Search app it is automatic, although on third party sites it will prompt whether you want to use the app or not, offering to always use the association.

Click on that link in newer versions of Android (in a rendering agent that leverages the standard launch intents), with IMDB installed, and you’ll be brought to the relevant page in that app.

Instant Apps presumably entail a couple of basic changes-

  • Instead of devices individually having a list of app links (e.g. “I have apps installed that registered for the IMDB, Food Network and Buzzfeed domains, so keep an eye out for ACTION_VIEW intents for any of the respective domains“), there will be a Google-managed master list that will be consulted and likely downloaded/cached regularly. These link matches may be refined to a URL subset (where the current functionality is for a full domain).
  • An update to Android Studio / the build platform will introduce more granular artifact analysis/dependency slicing. Already this exists in that an APK is a ZIP of the various binary dependencies (e.g. for each target processor if you’re using the NDK), resources, and so on, however presumably the activities, classes and compiled resources will be bifurcated, their dependencies documented.
  • When you open a link covered by the master list, the device will check for the relevant app installed. If it isn’t found, it will download the necessary dependencies, cache them in some space-capped instant app area, initialize a staged environment area, and then launch the app.

They promise support, via Google Play Services, all the ways back to Android 4.1 (Jellybean), which encompasses 95.7% of active users. Of course individual apps and their activities may use functionality leveraging newer SDKs, and may mandate it as a minimum, so this doesn’t mean that all instant apps will work on all 95.7% of devices.



The examples given include opening links from a messaging conversation, and from the Google Search app (which is a native implementation, having little to do with HTML).

The system will certainly provide a configuration point allowing a device to opt out of this behavior, but it clearly will become the norm. Google has detailed some enhanced  restrictions on the sandbox of such an instant app — no device identification or services, for instance — but otherwise it utilizes the on-demand permission model and all of the existing APIs like a normal app (detailed here. As is always the case, those who don’t understand this are fear mongering about it being a security nightmare, just as when auto app-updates were rolled out there were a number of can you say bricked? responses).

And to clear up a common misconception, these apps are not run “in the cloud”, with some articles implying that they’re VNC sessions or the like. Aside from some download reductions for the “instant” scenario (Instant Apps are apparently capped at 4MB for a given set of functionality, and it’s tough to understand how the rest of the B&H app fills it out to 37MB), the real change is that you’re no longer asked — the app is essentially forced on you by default — and it doesn’t occupy an icon on your home screen or app drawer. It also can’t launch background services, which is a bonus.

Unfortunately, the examples given demonstrate little benefit over the shared-platform HTML web — the BuzzFeed example is a vertical list of videos, while the B&H example’s single native benefit was Android Pay — though there are many scenarios where the native platform can admittedly provide an improved, more integrated and richer experience.

It further cements the HTML web as a second class citizen (these are all web service powered, so simply saying “the web” seems dubious). I would cynically suggest that the primary motivation for this move is the increased adoption of ad blockers on the mobile HTML web: It’s a much more difficult proposition to block ads within native apps, while adding uBlock to the Firefox mobile browser is trivial, and is increasingly becoming necessary due to the abusive, race-to-the-bottom behaviors becoming prevalent.

And it will be approximately one day before activities that recognize they’re running as instant apps start endlessly begging users to install the full app.

Ultimately I don’t think this is some big strategic shift, and such analyses are usually nonsensical. But it’s to be seen what the impact will be. Already many sites treat their mobile HTML visitors abusively: one of the advocacy articles heralding this move argued that it’s great because look at how terrible the Yelp website has become, which is a bit of a vicious cycle. If Yelp can soon lean on a situation where a significant percentage of users will automatically find themselves in the app, their motivations for presenting a decent web property decline even further.

1 – I have no inside knowledge of this release, and of course I might be wrong in some of the details. But I’m not wrong. Based upon how the platform is implemented, and the functionality demonstrated, I’m quite confident my guesses are correct.

Okay, got it

Earlier this year (2015) I put out an app for Android called Gallus. As regulars know, it was a stabilizing hyperlapse-capable video recorder for Android (unlike Instagram’s solution on iOS, it wasn’t just for stabilizing hyperlapses, and offered a variety of other features including interval frames, locked focus/exposure, advanced filters, etc). Everyone else will know nothing about it given that it was incredibly obscure, but regardless it captured the attention of a couple of industry heavyweights, making the whole effort worthwhile.

I’m very proud of what I built. The Nexus 6p — a recent addition to my device portfolio — is the first device to really showcase what the app is capable of, and I consider the project an enormous personal success.

Gallus was very technically challenging, and did something claimed impossible (still not achieved by anyone else). It doesn’t work great on every device, though, because not every device in Android land is great. And when someone has a device with a terrible gyroscope or a system image with invalid field of view settings, they’re going to blame Gallus and not their device. Such is the fun of the Android world if you’re doing anything more than a couple of basic forms1.

But it had a terrible interface as the technology was my focus, not the UI. The settings page was just awash in obscure settings to alter (owing to the extreme variance of Android devices, an issue that makes such a solution magnitudes harder than doing the same on iOS), and the main interface…well personally I thought it was perfectly fine, but a lot of users seemed to have incredible trouble figuring it out.

While I understood every complaint about the mess of a settings page, the difficulty with the main interface surprised me: The iconography wasn’t completely literal, but it was built with the intention that users would just try the buttons and quickly discover what each does. This was a wrong assumption, as a recurring feedback trend were users toggling basic settings off and then complaining about the result. Stabilization, for instance, is a toggleable button with a “shaking camera” on it, only available during playback/preview, yet a number of users would disable this, apparently inadvertently, and then complain about stabilization no longer working. Another button lets you disable/enable smartzoom (a toggleable button with “crop” iconography on it), yielding a result where the frame jumped around in the render (although the actual scene was perfectly stabilized, and personally I think was a fantastic solution and I prefer it over forced zoom), and again people would disable it and then complain about weird black bars appearing around their video.

Many people have more time and motivation to complain than they do spending seconds trying out buttons to figure out what they do. This isn’t a “resent the user” statement, but is a learned observation and I suppose could be considered beneficial: For every user that complained about a trivial interface, how many more just uninstalled and moved on?

I always intended to do some sort of inline help. The “wizard” sort of thing that does bouncing arrows and walkthroughs of the interface as a series of steps: This is how you enable/disable stabilization. This is how you render to a video file that you can share. Etc. It was never financially worth the time or effort (for a free app with no ads or monetization beyond being a vehicle to pitch some technology), but if I were going to do something that was my imagination of how I would. In a way sort of like the obnoxious “tutorial” stage of many games where you try clicking past each forced interaction as quickly as possible.

Which was all a big egotistical way of getting to the real subject of this post, which is that Google recently started filling all of their Android apps full of “Okay, Got It” staged tutorials. When you open that newly updated camera app it has a multi-step tutorial. The same for Gmail, Google Maps, and so on. Generally these appear on first run, though they seem to keep retriggering them on minor updates even though the information hasn’t changed, and force you to step through the various pages before you can use the app.

It’s amazing how quickly “Okay, got it” fatigue sets in — it’s a concept that works in isolation, but diminishes in value at scale. While I imagine that it benefits green users, to most established users it quickly becomes a nuisance. As I’ve talked about before, the worst time to pester users is when they start the app. When I’m sitting on the side of the road in Niagara Falls trying to find my way out of some suburban enclave, having my navigation request bring me to a Google Maps tutorials wizard is not wanted, needed, or beneficial. When I pull up the camera app to take a picture of a quickly passing moment, having the camera use that moment to teach me how to use it is…well it’s the worst possible moment for it.

There has to be a better solution. Some sort of master help interaction of the platform, triggered and observed by any app that decides to. The Okay, Got It approach does not scale, and already I’d say I’ve seen less than 5% of the content of these screens.

1 – Recently there was a bit of a hoopla around various camera apps not working correctly with the Nexus 5x. To explain this issue, the image sensor can be mounted in two variations relative to the natural portrait position of the device. It just turns out that for the rear camera every single device all did it a single way, to the point that it was assumed to be a given and many apps didn’t even have a code path for the alternative. The obvious conclusion is to standardize this (it should never have been a variation to begin with, but at this point should be entrenched), and if the sensor is inverted, flip it at the system level before presenting it to the application. To minimize the hassle every single app has to go through when this could be standardized at higher levels. I’ve complained about this before, where instead of doing the work at the system level, it becomes a problem for every app developer to deal with, often poorly.

Not for Google though, and you see this endlessly throughout Android: Simple things that should be standardized either as a demand of the hardware, or as a shim standardization offered by the system, are not, so every app has to have countless permutations. To make it worse, you then have to just hope that your permutation actually works, or obtain every possible variation of device. I have sensor rotation code in Gallus, but I have no idea if it actually works correctly on the Nexus 5x (I mean I know it should work, but many times there has been a schism between how I think things will work and how they actually do, so I say that with no confidence).

Quadrilateral Texture Projections

In trying to diagnose a unique device fault in some rendering contexts — specifically on the Nexus 6 when rendering non-power-of-2 OES textures to a quadrilateral with projection mapping (a scenario that occurs with Gallus when it is performing perspective corrections) — I threw together a quick and ugly Android Studio solution that might prove useful as a starting point for those looking to play around with Android development.

A simple application that loads a texture and displays it in a moving and warping quadrilateral, demonstrating both projected and unprojected texture mapping, switching with a touch.

Hopefully it’s useful and interesting to someone. It’s very simple, and is not tech bravado, but it does a straightforward task well.

Though it didn’t demonstrate that assumed fault with the Nexus 6, using just a standard power-of-2 checker board texture.

Losing Users — Android’s Cognitive Load of Updates versus Features

I haven’t updated Chrome in years. At least I haven’t intentionally updated Chrome. When I look at the version number I see it’s version 43.0.2357.124, apparently a vintage from earlier this month, and when my development veers to the web I know they’ve been constantly expanding and improving the browser, but there is zero effort on my part to keep it up to date.

It doesn’t intrude upon my work, or demand my attention in any way. The updates simply happen. Amazingly this approach was somewhat controversial when first used1.

There are no checkpoints where I have to mentally decide “is this worth the hassle?”. I don’t need to do anything to maintain it.

When I open Notepad++ or Filezilla, in contrast, or a number of other apps that follow a similar pattern, the very first thing they often do is present a “deal with it now” update notice. If I were just casually opening apps for maintenance purposes this might be reasonable opportunity, but given that I opened them for the purpose of getting something done I’m prone to just delaying the update for the next open where the same pattern repeats.

Barring a critical security update, it’s the worst possible time to ask for an update. Some of the more considerate apps at least download the update in the background and are ready to finish the process as painlessly as possible, while others drop you to a webpage.

Add that on the desktop the tragedy of the commons played out and many users are wary of updates: Updates often aren’t to enhance the user experience, but instead pursue another roll of the dice at installing crapware (e.g. Java): Maybe this time time you’ll forget to uncheck that box.

This all circles back to three recent posts/articles that caught my eye-

1-The Story of AppChat, and Why Android is a Better Platform for Startups than iOS

2-The Next Feature Fallacy: The fallacy that the next new feature will suddenly make people use your product

3-New data shows losing 80% of mobile users is normal, and why the best apps do better

The first observes that Android is a great platform for iterating because you can roll out updates with ease, quickly and unconstrained. The second theorizes that adding the next feature won’t make people use your product. The last shows how most users uninstall apps in a pretty vicious curve.

These all, to some degree, have context in my own limited experience building Android apps, and my rough experience relative to each article would be-

1- Android does let you iterate quickly, but…

2- …frequent updates might not offer enough benefit given that…

3- …every update is a checkpoint where some percentage of users will decide to just uninstall your app. There is a cognitive load with each update.

Android 2.2 added optional auto-updates to apps (seeing the same “it’s going to brick your device!” fear mongering that desktop updates saw), however unlike iOS where apps often just exist in their most contemporary state, dutifully kept up to date, on Android even when auto-updates are enabled there are — in my opinion — some critical faults of defaults, still there in Android M, that make each update a roll of the uninstall die.

  • If you happen to open your device before the update was downloaded and installed, but when it’s aware of it, it will present it as if the permissions changed, seemingly demanding manual intervention
  • even if it didn’t demand a manual intervention, after the installation the device will treat the update as a critical notification. When you check your phone to see what important notices have arrived, you’ll be informed of the very important information that Some App Updated. If I updated it multiple times in a day, you’d receive this notice multiple times during the day

This seems pretty marginal — big deal that an app updated — and it should be, but it’s like notification spam: However minimal it may seem, to users it seems Important, because the system presents it as if it’s important. It seems like something that demands attention.

Facebook changed in some random way. Probably, as 90% of app updates are described, “Performance improvements and bug fixes.” Great.

A good example of this issue would be the Google Android System WebView. Essentially the Chrome wrapper used in other apps to present web content, it has had sporadic periods of frequent updates.

Remember that this is a largely hidden background system component. It has 63,000+ ratings, and thousands of reviews.

After each update, presented on every single Android device as an important notification that needs to be dismissed, a number of reviews appear demanding to know what changed. The users, most of whom have no idea what the component is, need justification for this intrusion into their lives. It turned into a bit of an ongoing joke where people are now leaving humorous reviews.

This is for a system component that can’t be uninstalled. It is what it is, and however informed and active the user may be they really don’t have much say in the matter.

Now imagine that we’re talking about a video stabilization and hyperlapsing app: Through raw luck someone was made aware of it and decided to install it (it is, after all, one of the most advanced applications on the Android platform). Realistically it isn’t going to get used often — it really is a niche app — but ideally they have it available that moment when it’s the perfect solution. Say once a month.

Like the vast majority of apps it isn’t critical to have installed, but it’s nice to have available in some situations. These are the long tail of apps that fill occasional needs — shooting a stabilized video or creating a hyperlapse, finding a bank machine, looking for a pickup game of basketball, etc. Not every app has the engagement levels of a social media app, nor should they.

Now push a number of updates as amazing new features are added and bugs are fixed for unique device faults.

Every single time an update comes in is another checkpoint where those users pay a price, so to speak, for the app, it seemingly demanding their attention (even if those updates were automatically installed). At that moment, whatever their emotional state may be, they re-evaluate whether it was worth the mental load it demanded.

Push ten updates between uses, each time causing the users to reconsider the “worth it” evaluation, and you’re going to see uninstalls. They might even love your app but figure they can just reinstall it the next time they have the need, though given that it’s unlikely they’ll remember the name you’re back at square one.

I’ve seen this first hand: the best way to cause a precipitous drop in active installs is to push an update. Even if the update made the app that much better2, adding some incredible new features, it’s a forced interaction where some users just decide to uninstall. An update notification can never possibly improve the installed base — people who don’t have your app aren’t made aware of the great new things — but someone irritated about a coworker or late for the train or inundated with device notifications isn’t going to meet it with open arms.

There is a cognitive load to every Android update, even when fully automated. The advice of article #1 may work when you have a captive, engaged audience, but for many apps each update is just another chance to lose users. As a user of Android I’ve demonstrated this behavior, uninstalling games that I occasionally play and utilities I occasionally benefit from, because I feel like I’m being spammed with updates, at no fault of the creators (who are trying to diligently maintain the app).

I don’t particularly care or need to know that Facebook updated. It isn’t so important that it needs to be expressed on my lock screen. Hidden away in some app updates section, sure. Of course it should be restricted from exhausting the durability of my flash or downloading excessive data, and maybe a notice for those sorts of events would make sense (e.g. “Some App updated 46 times in the past 24 hours, requiring 16GB of downloads”), but realistically that is not even within magnitudes of being a problem for the scenario I’m discussing. That video application I mentioned is 2MB in APK form.

All of this is just a checkbox or two away — the Play Store settings allow you disable notifications for both when updates are available, and when they are applied, but the default for both is to show notifications. Those defaults are what the overwhelming majority of devices are going to run with. And they work against you when you run with the “update often” approach.

1 – Though it is evil when every software package runs a perpetual daemon to check for and apply updates. Every OS has scheduling mechanisms that could easily be used without yet another piece of software clogging the task list, checking a website once a day.

2 – Though to some degree the same tragedy of the commons plays out in apps that played out on the desktop. Users have become accustomed to updates making apps worse rather than better. Adding or making more intrusive ads. New pleas for in app purchases. Etc.