Tales of a Developer Advocate

... and other things

Living with Web Apps

As a Developer Advocate for Google Chrome and the Web it is my job to build a picture of how the Web works and educate developer on how to build for it, but also craft a vision for how developers should build for the future starting today.

I am a firm believer that we should be building and deploying apps on the web powered by a runtime that is the browser. The web offers a medium that is frictionless for user to engage with. A user can just visit your URL… you get it, but can we go day to day using just the web on mobile?

I decided to spend a day using only the web for all the tasks that people use their mobile phone for. No exceptions. Everything interaction that I do must be via the web.

TL;DR — the 10 deadly sins of a mobile web app — You can get stuff done, but there are a lot of rough edges that stop you from doing the things that you need to. Some of the issues are not anything the developer can do just yet, it is the platform that they are fighting against. Luckily, I know what is coming on the platform so I am very optimistic that the feature gap will be reduced for Apps on the web.

Ultimately this experiment has shaped the way that I want us (Chrome Developer Relations) to get developers building for the web today and tomorrow.

  1. It’s not mobile: Some of the newer services have good mobile web experiences but there are huge areas where web developers still think desktop first or desktop only.
  2. Lack of focus: It sometimes feels like Web Apps are often considered as documents with functionality in. There is some functionality, then a document thanking everyone who helped. Play 2048 as an example.
  3. Discovery is a massive issue: Finding great web apps is incredibly hard and I have little confidence that they work well on mobile even when I see a top link in Google.
  4. Everything is ephemeral: This is great for a lot of experiences; I pick up a site use it once and I am done. There are a huge number of apps — all communications apps for example — where I need the app to live in the background to be able to deliver notifications but they can’t.
  5. It’s not interconnected: Everything appears to operate in a silo or everything is tightly coupled to a service. I don’t use dropbox, I use drive, now I can’t use your service to save my stuff. I light-weight mechanism for interconnecting apps would really help.
  6. Everything is monolithic: I found it incredibly hard to find small self-contained mobile apps that just solved my problem without being a service that I had to sign-up for and adopt.
  7. Everything needs credential but nothing keeps credentials: I have to either create an account or re-sign in to everything all the time. I can’t tell if it is a hangover from the shared desktop era that means web apps must be logged out after use. This is not something I experience in many mobile apps. I log in once.
  8. It’s slow and ugly out there: There is a serious lack of polish in many experiences; I had very little confidence that the apps would offer what I wanted when I found them and when I used them there were a lot of jarring animations and transitions.
  9. White screens rule the day: Offline was not a big issue for me, however white pages in transitions really annoyed me; I found myself just waiting for the screen to load and getting frustrated when my entire UI was rebuilt.
  10. The platform has a lot of features, just not the right ones: This is a meta-point, but if feels like the API space on the web does not yet cater for even the basic type of interaction with my device that I need; Notifications and Push Messaging were greatly missed.

There are about apps that I want to build now. I am sorely tempted to start a movement getting people to build good utility apps.

Journal: The Experiment

11:30 PM — The night before the experiment
If I had been smart marketing type person I would have run this experiment on Wednesday, but alas I am a simple man with simple ideas.

The night before “Web App Thursday” — an evening I like to now call Shrove Wednesday, a day of native app gluttony —  I set up my home screen to launch the apps that I use regularly.

My homescreen

The first thing that I noticed is the inconsistent usage of launcher icons across all service. Services that you would expect to have good “app” icons just don’t (notably all by the company that I work for — bugs have been raised) many services that I relegated to my 2nd screen didn’t even have favicons.

It totally slipped my mind that I needed to replace the camera, dialer and SMS. Later when I realized to further compound my issues I had an existential crisis about the browser being a native app, but I chose to ignore that and keep this simple.

With my “workflow” set up I went to bed, watched some QI from the Netflix App that was integrated with my Chrome Cast. Bliss…


5:53 AM — Youngest son sits on my head to wake me up
Seriously. He sits on my head.
Groggily I roughly remember something about only using the web today before I fall back asleep.

6:00 AM — Web App Thursday. BZZZZ. BZZZZ. BZZZZ

Alarm wakes me up. Trundle across to my phone to snooze the damn thing and start to feel optimistic about my day using only the web on my phone. Now I am not the sharpest fork on the shelf, but as I am walking to the loo (phone in hand) I realize that I have already failed. Alarm clock is a Native App.

Whilst I deal with the fact that I am a failure I notice that it is impossible to find web based alarm clock apps that work on mobile which kind of makes sense; There is no API yet that will let you background an app and get it to wake up at a specific time. However the more frustrating this is that even countdown timers are hard to find and when you do find them in search they are all aimed at desktop.

Some people have managed to get around the API issues by using Flash but:

  1. Flash is not an option on mobile
  2. You have to have the page always open
  3. They are ugly

6:15 AM — …
6:25 AM — The dead leg walk downstairs
Enthused that the rest of my day was likely to be gassing on Twitter or checking emails I reset my experiment status.

At this point I also thought I need a shift in narrative; logging everything by time is a pain (I can’t find a good app for it). Not only is it hard to write like this, but it also really hard to find an app that keeps a time ordered log of what happened and when.

It is a lot easier to write based on the tasks that I needed to complete during the day.

Use cases

I took copious notes during the day of things that worked well and areas that were frustrating. I have broken the results down into use cases that were important to me.

Being prompted at certain times

I found a couple of Countdown timers but that is about it. Alarms are pretty much standard on mobile devices so there is a question about the need to do this on the web. I only wanted to do two things:

  • Set a quick alarm based on a fixed time
  • Quickly set a countdown for X minutes

The latter we can do, but I can’t find good apps. The former can’t be done when the browser is backgrounded.

Note taking

I did a quick search for a note taking apps on the web and there were a few but interestingly my overriding need was something that I could just quickly start taking notes in. I didn’t want to sign up for services or cloud integration, I just wanted to start taking notes.

I use Google Keep at work and have never tried it on the web on mobile but I thought I should give it a go I couldn’t really find anything better quickly.

To my surprise Google Keep works quite well on the mobile web. With a couple of exceptions:

  1. It can’t run full screen like a native app, it doesn’t even have a launcher icon.
  2. I can’t share something to it (like a link) to create a note
  3. The navigation bar Janks.
  4. Offline… er, no.

Communicating with People

A lot of my time on my phone is spent communicating with people. Email, Twitter, G+ and SMS are my main medium, voice less so.

During the day Email (gmail in particular) worked well although it is out-dated in terms of modern web based UI’s with some quirks in the typing experience and that focus highlighter is annoying.

Twitter also worked pretty well, I could post, DM and search. It launches fullscreen, it feels like an app (heck I can even load it offline) and it loads very quickly and provided 90% of what I needed. The web experience on mobile is still last years site, it doesn’t look like any of the native mobile experiences.

Twitter and Email were the first apps that I noticed that the “ephemeral” nature of the web significantly hindered my ability to communicate with friends and family. Earlier in the day I had turned off system notifications and none of these experiences have the ability to live in the background and notify me when an interesting interaction occurs. After about 4 hours of a quiet morning I ended up turning them back on so at least I knew when I should check for updates.

The web is not fully integrated in to the native communication stack. There are no dialers. There are no Web based SMS apps and whilst you can just about create an SMS from the web, you can’t send or read them directly via a web app. I have an open question about

Reading News and Content

Hacker News and Reddit are terrible on mobile. Seriously, I don’t get why they don’t even try. I am being hard on Reddit because they have at least .compact but they steer everyone away into apps.

I am an extensive user of Google Play Newsstand app on Android, it does a decent job of getting me the content I want to read both Purchased and also “web available”. I had no idea what to expect checking this site on the mobile web and to my surprise I can read my subscription content but it is a bare bones experience, there is no ‘text’ mode (it is only images) and the gestures don’t work the same. I was disappointed to find that the “web article” reading mode is not supported at all.

Many news sites worked great (even if they did m.* redirects). None of them felt like “app experiences” and this is interesting because many news sites are reporting more engagement and reading inside apps.

Watching Video and Listening to Audio

I watch a lot of video and listen to podcasts quite frequently and I wasn’t expecting a huge amount in terms of mobile web experience.

I made sure that I used the mobile web version of YouTube. It is a pretty good experience although it lacks the UX smoothness of the native app. I did find that very frequently the browser wouldn’t render any of the visible content (but would play the video) and I wasn’t able to isolate the exact circumstances.

I was very pleased to find that Google Play Movies works even with protected content. There were a couple of small scrolling issue left to right and the media player appears to be YouTube. Whilst the entire UI is very clunky and slow it works.

For podcasts Player.fm is my client of choice and it works pretty well on mobile. The audio plays even when I background the application, however there are no controls to let you play or pause the sound or even get back to the site easily once you have backgrounded Chrome.

Camera

My two sons were doing something cute and I needed to take a photo quickly. As far as I can tell there are no “Camera apps” on the web for mobile, ones I found were optimized for desktop, used Flash and didn’t save directly to my phones gallery.

Once I had taken the photos, I wanted to quickly crop the images and apply some filters to share them out. Yup. You guessed it. I couldn’t find any apps that do this.

This is one of the areas where I completely bailed on the web and it frustrated me. I can’t retrieve and modify the photo’s on my device in a seamless manner.

I also took some time to think about how a developer might build the camera experience and naturally my first thought was to use “getUserMedia” API. If you look further into this API then it doesn’t offer any advanced features that you expect in a good camera app: focus, flash, zoom etc. It is clear that this API has been designed for use in P2P applications and not as a dedicated camera experience.

Gaming

I found one great game during the day that took up a good chunk of down time: Game about Squares is a brilliant, simple, mobile optimized game. Don’t get me wrong, 2048 is a great game and it works on the mobile web however it has a very document feel to it.
I found that games suffered all the same problems of Apps: I can’t find them, they feel like documents rather than apps and more often than not they are still desktop games.

Pervasive Issues over the day

Lack of Confidence

I really had no confidence in many of the apps that I found.

  • Some experiences I wanted them to load instantly when launched, the white screen for loading felt like I was gambling at every moment.
  • I got a white screen so frequently it got really frustrating when transitioning between pages that I couldn’t tell if it was Chrome or the App that is causing the problem or just the way we build apps.
  • I had no idea that any of the apps would do what I wanted.

White screens follow me around everywhere

In nearly every app and site I used I felt like the majority of my time was spent waiting for content to load. It was really frustrating, when I use native apps I very rarely get this. Whilst I see in natvie apps that there are placeholders for the content to load I still get to see the entire app UI.

Jank/Stutter is pervasive

Watching UI elements move on the screen was toe-curling. Navigation trays seemed to be a big offender during the day. I would often click on the tray icon, wait, and then see a 4fps animation.

That being said, there are some sites that work really well. The twitter app and g+ app both have really great scrolling on my phone.

Notifications

I knew going in to this that we don’t have background push messaging and notifications, but it is not until you don’t have them do you realise it is one of the primary ways that you engage with your applications on your device.

Form filling

I tried to book my hotel that I stay in during the week on mobile. I had to bail and go to desktop, it was terrible. The site wasn’t optimised for mobile, but at the same time I was just cautious anytime that I had to enter text.

Sharing Content

There are lots of things that I create on my phone every day and I can’t share them with any web services. When I took a picture of the kids I was forced to take the photo with an app and share it via an app. Likewise when I wanted to share something from the browser I couldn’t share it to any other web experience, I kept having to share it to a native app.

Add to this Chrome is pretty poor at sharing content natively. You can’t long press on images or links and share them out (these were the only things I needed to share in the day).

Lack of basic device interaction

I get that we have access to geo-location and device orientation, but I also found that I wanted to do simple things such as selecting and saving images to and from my photo gallery in a near seamless fashion and I couldn’t do it. If I was playing audio on a page I would have loved to be able to control that from the lock screen and I couldn’t do it, I had to go tab hunting. I also really wanted to have a camera app that I could trust and do basic actions on (focus and flash) and I couldn’t do it.

Discovery

It is hard to find apps. It is even hard to find good apps that work well. It felt impossible to find good apps that work well and have a nice user experience. I had to rely on my social network to find apps. Search sometimes did find web apps for some common use-cases, but it doesn’t rank quality. Both the Chrome Web Store and Firefox marketplace are not great, CWS is impossible to navigate on mobile, FF is a lot better. Neither let you launch a hosted web app directly from an app result.

This was so frustrating, the only places that I know has apps and I can’t do anything with it.

Lack of small utilities

Most of the time I wanted some small apps to help me complete a task, these might exist, but even after deep searches for them the utilities are primarily desktop only, horrible user experiences, large services that need registration or they don’t exist. There are about 20 simple core utility apps that we should build on the web and market them as “the primary” web experiences.

This is the web platform

Feature On Desktop On Mobile
PNG alpha transparency Yes Yes
querySelector/querySelectorAll   Yes
getElementsByClassName   Yes
CSS3 Multiple backgrounds   Yes
CSS3 Background-image options   Yes
CSS Table display   Yes
CSS Generated content   Yes
CSS 2.1 selectors Yes Yes
CSS3 selectors   Yes
CSS3 Text-shadow   Yes
CSS3 Colors   Yes
CSS3 Box-sizing   Yes
CSS3 Media Queries   Yes
CSS3 Multiple column layout   Yes
Canvas (basic support)   Yes
Cross-document messaging   Yes
Data URIs   Yes
XHTML served as application/xhtml+xml   Yes
CSS3 Opacity Yes Yes
JSON parsing Yes Yes
CSS3 Text-overflow   Yes
CSS3 Overflow-wrap Yes Yes
CSS min/max-width/height Yes Yes
CSS inline-block Yes Yes
dataset & data-* attributes Yes Yes
CSS Counters   Yes
getComputedStyle   Yes
contentEditable Yes  
Drag and Drop Yes  

Pretty damning.

At “100%” coverage of features that are in all browsers split by Mobile and Desktop then this is all we have to play with.

Ok, this is actually misleading. If you are willing to miss out on 1% extra reach for your desktop audience then you can get similar feature parity with mobile. But still the feature support that is ubiquitous across the web is actually pretty small especially if you are supporting IE8.

How do I know what the web platform is?

Last year I built iwanttouse.com to make it easier for you to determine the cost on your userbase supporting certain features will have. If I support X, I can only reach Y% of the web’s users

The project is pretty simple. It is a projection of the data on CanIUse.com. For a given “feature” it looks for the earliest version on a platform that it was supported on and sums the “usage”.

I split the feature set by Mobile and Desktop and it gives you some pretty interesting nuggets of data.

Two things that fell out of this:

  • Features for Free. If I choose Web Audio (43% on mobile) I can also safely use other features such as Server-sent DOM Events because all browsers that support the former support the latter. (Note: the inverse relationship is not always true)
  • Ubiquitous Platform features. As above but platform features that we can rely on being present in all browsers with any significant share.

I want to focus on Ubiquitous Platform features.

How do we improve the web platform?

As a web developer today I face a couple of problems: Legacy browsers that aren’t updated and inconsistent implementation across browsers.

The web feels like a pirate ship, everyone is hacking and slashing in different directions and we are lucky enough that the ship goes forwards. Slowly. How do we become a Ben Ainslie America’s Cup winning yacht?… (Ack, I can’t believe I said that). Point is, how can we improve the modern mobile web consistently if there are multiple large players in the eco-system?

  1. Wait it out and let the Browser vendors do their thing. This will change over time as people move off the platforms that have stopped progressing as their devices are renewed.
  2. Ignore the old browsers and the users that use them and go for it.
  3. Push for consistency across the platform.

My preference is for 2 and 3. But actually 1 is what we really really need to solve.

I like to solve level 1 problems — problems with a technical solution — they’re the things I can fix. I can meet developers and work with them on their sites to measurably make the web better one large site at a time, but it is all small scale…

I decided to take a peek at the features that are supported across the latest mobile browsers and the reach that will have: 44%. We can’t honestly say to a business that you should build experiences for 44% of your potential user base (well, it depends who you want to sell or attract - your demographics might be highly skewed - i.e.. Government legislation, Business demands.)

If you look at the head of the mobile web (44%) there is a compelling feature set. You can build some amazing applications with it.

Feature Android Browser 4.4 iOS Safari 7.0 Chrome for Android 32.0 IE Mobile 10.0 Opera Mobile 16.0 Firefox for Android 26.0 Blackberry Browser 10.0
XHTML served as application/xhtml+xml Yes Yes Yes Yes Yes Yes Yes
XMLHttpRequest 2 Yes Yes Yes Yes Yes Yes Yes
WOFF - Web Open Font Format Yes Yes Yes Yes Yes Yes Yes
Web Workers Yes Yes Yes Yes Yes Yes Yes
Web Sockets Yes Yes Yes Yes Yes Yes Yes
Video element Yes Yes Yes Yes Yes Yes Yes
ECMAScript 5 Strict Mode Yes Yes Yes Yes Yes Yes Yes
Typed Arrays Yes Yes Yes Yes Yes Yes Yes
CSS3 Transforms Yes Yes Yes Yes Yes Yes Yes
CSS3 Text-overflow Yes Yes Yes Yes Yes Yes Yes
SVG in HTML img element Yes Yes Yes Yes Yes Yes Yes
Inline SVG in HTML5 Yes Yes Yes Yes Yes Yes Yes
SVG filters Yes Yes Yes Yes Yes Yes Yes
SVG in CSS backgrounds Yes Yes Yes Yes Yes Yes Yes
SVG (basic support) Yes Yes Yes Yes Yes Yes Yes
defer attribute for external scripts Yes Yes Yes Yes Yes Yes Yes
async attribute for external scripts Yes Yes Yes Yes Yes Yes Yes
requestAnimationFrame Yes Yes Yes Yes Yes Yes Yes
rem (root em) units Yes Yes Yes Yes Yes Yes Yes
querySelector/querySelectorAll Yes Yes Yes Yes Yes Yes Yes
PNG alpha transparency Yes Yes Yes Yes Yes Yes Yes
Page Visibility Yes Yes Yes Yes Yes Yes Yes
CSS outline Yes Yes Yes Yes Yes Yes Yes
Offline web applications Yes Yes Yes Yes Yes Yes Yes
Web Storage - name/value pairs Yes Yes Yes Yes Yes Yes Yes
CSS3 Multiple backgrounds Yes Yes Yes Yes Yes Yes Yes
CSS min/max-width/height Yes Yes Yes Yes Yes Yes Yes
matchMedia Yes Yes Yes Yes Yes Yes Yes
JSON parsing Yes Yes Yes Yes Yes Yes Yes
Range input type Yes Yes Yes Yes Yes Yes Yes
input placeholder attribute Yes Yes Yes Yes Yes Yes Yes
CSS inline-block Yes Yes Yes Yes Yes Yes Yes
sandbox attribute for iframes Yes Yes Yes Yes Yes Yes Yes
New semantic elements Yes Yes Yes Yes Yes Yes Yes
Session history management Yes Yes Yes Yes Yes Yes Yes
Hashchange event Yes Yes Yes Yes Yes Yes Yes
getElementsByClassName Yes Yes Yes Yes Yes Yes Yes
getComputedStyle Yes Yes Yes Yes Yes Yes Yes
Geolocation Yes Yes Yes Yes Yes Yes Yes
@font-face Web fonts Yes Yes Yes Yes Yes Yes Yes
FileReader API Yes Yes Yes Yes Yes Yes Yes
CSS3 Colors Yes Yes Yes Yes Yes Yes Yes
CSS3 Transitions Yes Yes Yes Yes Yes Yes Yes
CSS3 Text-shadow Yes Yes Yes Yes Yes Yes Yes
CSS Table display Yes Yes Yes Yes Yes Yes Yes
CSS3 selectors Yes Yes Yes Yes Yes Yes Yes
CSS 2.1 selectors Yes Yes Yes Yes Yes Yes Yes
CSS Repeating Gradients Yes Yes Yes Yes Yes Yes Yes
CSS3 Opacity Yes Yes Yes Yes Yes Yes Yes
CSS3 Media Queries Yes Yes Yes Yes Yes Yes Yes
CSS Gradients Yes Yes Yes Yes Yes Yes Yes
CSS Generated content Yes Yes Yes Yes Yes Yes Yes
CSS Counters Yes Yes Yes Yes Yes Yes Yes
CSS3 Box-shadow Yes Yes Yes Yes Yes Yes Yes
CSS3 Animation Yes Yes Yes Yes Yes Yes Yes
Cross-Origin Resource Sharing Yes Yes Yes Yes Yes Yes Yes
contenteditable attribute (basic support) Yes Yes Yes Yes Yes Yes Yes
classList (DOMTokenList ) Yes Yes Yes Yes Yes Yes Yes
Text API for Canvas Yes Yes Yes Yes Yes Yes Yes
Canvas (basic support) Yes Yes Yes Yes Yes Yes Yes
calc() as CSS unit value Yes Yes Yes Yes Yes Yes Yes
CSS3 Border-radius (rounded corners) Yes Yes Yes Yes Yes Yes Yes
CSS3 Background-image options Yes Yes Yes Yes Yes Yes Yes
Audio element Yes Yes Yes Yes Yes Yes Yes
Cross-document messaging Yes Yes Yes Partial Yes Yes Yes
CSS3 3D Transforms Yes Yes Yes Partial Yes Yes Yes
MPEG-4/H.264 video format Yes Yes Yes Yes Yes Partial Yes
Data URIs Yes Yes Yes Partial Yes Yes Yes
dataset & data-* attributes Yes Yes Yes Partial Yes Yes Yes
CSS position:fixed Yes Partial Yes Yes Yes Yes Yes
Content Security Policy Yes Yes Yes Partial Yes Yes Yes
Blob constructing Partial Yes Yes Yes Yes Yes Yes
CSS3 Overflow-wrap Yes Yes Yes Partial Yes Partial Yes
Progress & Meter Yes Partial Yes Partial Yes Yes Yes
Flexible Box Layout Module Yes Yes Yes Partial Yes Partial Yes

But like I said. 44%. It’s a big head but not a feasible platform for the vast majority of companies. I produced the following breakdown of features that we should get Chrome and other vendors to fix feature support at a tactical level to make for a more consistent web and make developers lives easier. The problem is we are only fixing it for 44% of the web’s users. Documented below for consistency

Feature Android Browser 4.4 iOS Safari 7.0 Chrome for Android 32.0 IE Mobile 10.0 Opera Mobile 16.0 Firefox for Android 26.0 Blackberry Browser 10.0
TTF/OTF - TrueType and OpenType font support Yes Yes Yes Unknown Yes Yes Yes
Touch events Yes Yes Yes No Yes Yes Yes
Navigation Timing API Yes No Yes Yes Yes Yes Yes
Mutation Observer Yes Yes Yes No Yes Yes Yes
Intrinsic & Extrinsic Sizing Yes Yes Yes No Yes Yes Yes
Font feature settings Yes Yes Yes No Yes Yes Yes
File API Yes Yes Yes No Yes Yes Yes
Server-sent DOM events Yes Yes Yes No Yes Yes Yes
CSS3 tab-size Yes Yes Yes No Yes Yes Yes
Channel messaging Yes Yes Yes Yes Yes No Yes
CSS3 Border images Yes Yes Yes No Yes Yes Yes
Blob URLs Yes Yes Yes No Yes Yes Yes
Viewport units: vw, vh, vmin, vmax Yes Partial Yes Partial Yes Yes Partial
SVG SMIL animation Yes Partial Yes No Yes Yes Yes
IndexedDB Yes No Yes Yes Yes Yes Partial
CSS3 word-break Partial Partial Partial Yes Partial Yes Partial
SVG fonts Yes Yes Yes No Yes No Yes
Download attribute Yes No Yes No Yes Yes Yes
Details & Summary elements Yes Yes Yes No Yes No Yes
CSS Filter Effects Yes Yes Yes No Yes No Yes
CSS3 Multiple column layout Partial Partial Partial Yes Partial Partial Partial
Date/time input types Yes Yes Yes No Partial No Yes
HTML5 form features Partial Yes Partial Partial Partial Partial Partial
Form validation No No Yes Partial Yes Yes Yes
CSS3 Box-sizing Partial Partial Partial Partial Partial Yes Partial
WAI-ARIA Accessibility features Partial Partial Partial Yes Partial Yes No
SVG effects for HTML Partial Partial Partial No Partial Yes Yes
matches() DOM method Partial Partial Partial Partial Partial Partial Partial
HTML templates Yes No Yes No Yes Yes No
Strict Transport Security Yes Unknown Yes No Yes Yes No
getUserMedia/Stream API No No Yes No Yes Yes Yes
Color input type Yes No Yes No Yes No Yes
CSS Feature Queries Yes No Yes No Yes Yes No
Clipboard API Partial Partial Partial No Partial Yes Partial
Canvas blend modes Yes Yes Yes No No Yes No
Ruby annotation Partial Partial Partial Partial Partial No Partial
Number input type Partial Partial Partial Partial Partial No Partial
DeviceOrientation events Partial Partial Partial No Partial Partial Partial
WebGL - 3D Canvas graphics No No Partial No Yes Partial Yes
Web Notifications Partial No No No Partial Yes Yes
Full Screen API No No Yes No Yes Partial Partial
WebP image format Yes No Yes No Yes No No
SVG fragment identifiers No No No Yes No Yes Yes
Shadow DOM Yes No Yes No Yes No No
WebRTC Peer-to-peer connections No No Yes No Yes Yes No
MathML No Yes No No No Yes Yes
Filesystem & FileWriter API No No Yes No Yes No Yes
CSS Masks Partial Partial Partial No Partial No Partial
Web Audio API No Yes Yes No No Yes No
WebM video format Partial No Yes No Partial Partial No
Datalist element No No No No No Yes Yes
CSS Hyphenation No Yes No No No Yes No
CSS Regions No Yes No Partial No No No
Promises No No Partial No No Partial No
Scoped CSS No No No No No Yes No
Shared Web Workers No No No No No No Yes
Opus No No No No No Yes No
Ogg/Theora video format No No No No No Yes No
JPEG XR image format No No No Yes No No No
Drag and Drop No No No Yes No No No
CSS resize property No No No No No Yes No
CSS Grid Layout No No No Yes No No No
Pointer events No No No Partial No No No
CSS3 object-fit/object-position No No No No No No No
Toolbar/context menu No No No No No No No
CSS Variables No No No No No No No
Blending of CSS image No No No No No No No

Getting these features implemented would be cool but there is no additional reach at all. More users will not be affected by these new features. We didn’t increase the size of the user base. Yes we might get an amazing WebGL based WebComponents app that people use but will they upgrade their browser or phone to be able to use it? Probably not.

So what do we do?

How do we move the web platform forward in a meaningful way?

It is hard.

Do we want to get back to a world where this is a thing?

best viewed in

Maybe.???

At a minimum we should:

  • Build for the 90% and get your partners and customers to see at a minimum the experience that you can build with a huge amount of reach.
  • Understand the choices you make and the impact they have. Push your customers and partners to use progressive enchancement. Don’t exclude a huge number of users for a single feature.
  • Push for consistency over new platform features across all browser vendors.

Tell me I am wrong

Using the Github API to optimise your workflow

It is no secret that Github is amazing. I don’t think it is widely known that they also have a very comprehensive Developer Platform.

Developer Landing Page

I admit it. I love the API. It’s an amazing example of how to build a platform.

Rather than fawning over Github, I really want to talk about the projects that I have worked on recently that take advantage of the API and roughly how we utilised this platform to optimise our workflows and experiences.

The first is HTML5 Rocks and the second is DevArt. I will only focus on HTML5 Rocks in this article (it turned out to be a lot longer than I planned).

HTML5 Rocks is a resource that we manage for web developers. It is entirely open source and the content licenced under Creative Commons. We host the site on AppEngine and the code on Github. Admittedly it is not obvious how we could use the Github API to help us.

The original process for deploying to HTML5Rocks was for a weekly “Sheriff” to monitor Github for any commit from the team or pull-request, git pull to a local repository, check the changes locally, run the site through a compressor and finally upload it to AppEngine.

Not only was it manual, you were flying blind. If you were the Sheriff you had no idea what was due to be launched that week. We used the issue tracker to manage the article pipeline but we couldn’t use the Milestones effectively because as a content site we didn’t work to milestones.

This process was tedious and could often be error prone. You were not a happy bunny if you were the weekly sheriff.

The first task was to make our article pipeline more visible for the entire team. We needed some sort of dashboard…

Working with Github Issues API

The Github API offers the ability to nearly fully manage your repositories issues. All of our articles that are due to be delivered are in the issue tracker. Combing the two we can automatically get a list of articles that are delivered and article that are yet to be completed.

Our new Workflow is:

  • Create an issue with some meta data (about the owner, the reviewer and the due date)
  • Work on your article in your own repo
  • Issue a pull request with the title “Fixes #[your issue number]”

That’s it. The system does the rest.

  • Github automatically closes the issue when the pull request is merged.
  • The system picks up this change, pulls down the latest code,
  • Regenerates the Calendar Dashboard
  • Commits the change and pushes it back up to Github.

This is pretty cool. We now have automated our article pipeline. This gives us greater visibility across the team as to what changed on a week by week basis. In this scenario, commits are not important but delivery of articles is.

Issues dashboard

The full code for this report generation is in our repository. We used PyGithub to simplify access to the API. To show how simple it is to use a summary appears below.

open_issues = repo.get_issues(state="open")
closed_issues = repo.get_issues(state="closed")

issues = []
[issues.append(i) for i in open_issues]
[issues.append(i) for i in closed_issues]
today = datetime.today()
completed_articles, late_articles, due_articles = ParseIssues(issues)

print "HTML5 Rocks Quarter Report for %s" % today.date()
print "=========================================\n"

print "Articles due this quater"    
print "------------------------\n"

if len(due_articles) == 0: 
    print "There are no articles due this quarter, either all is good, or something messed up!\n"
else:
    print "|Author|Article|Delivery date|Tech Writer|State|"
    print "|------|-------|-------------|-----------|-----|"

    for article in due_articles:
        print "|%s|[%s](%s)|%s|%s|%s" % ((article.assignee or article.user).name, article.title, article.html_url, article.due_on.date(), article.tech_writer, article.state)

See. Pretty simple.

This is great, but once the author has committed their article they still can’t see it live on the web. To make this easier we need to do a little more work.

I have not seen anyone auto deploy to App Engine via Github yet so I hope this serves as an example of how it is possible.

Deploying to App Engine from Github

If you have ever used AppEngine you will know that deploying a new build is often a manual process. It is a pain. Most developers don’t know that you can automate it using the command line tool.

If you can push live automatically, then all you really need to do is push the changes as they happen. The question is how do you get notified about changes to a repository as it happens? Polling? No.

Github use Webhooks. They are Amazeballs. WebHooks let you register a url that Github will call whenever there is a change to the repository. When you get this call you can automate some process on your system. It is that simple. It is very very powerful.

We then used a custom version of Github-Auto-Deploy to manage two read-only versions of site (staging and live.)

Github-Auto-Deploy is a rather amazing micro-server, it simply listens to GitHub Webhooks, pulls in the changes to the repository and runs a command. In our case the example command is as follows:

versionStr=${1:-master}
appcfg.py --oauth2 --version=$versionStr update ../

See the first line above? That lets us choose which appengine version we will deploy to, it is based off the name of the branch. By default any commit to the repository will push to our staging server. Any commit to repository to the live branch will push to the live site.

The interesting part here is that we can simply create a pull request from our master branch to our live branch branch and via the WebHook system we will have all the staged changes live and available to all of our users.

Merge from staging to live

We are pretty pleased with this process. We made it far easier to test changes on the web site and more importantly we took getting a change “live” from about 8 minutes to 10 seconds (excluding deploy time to appengine - about 30 seconds) and we saved our team a lot of frustration. An added benefit, although I can’t prove it, is that since the increases in deployment and testing efficiency we have seen a massive increase in external developer contributions.

With HTML5 Rocks we have only touched the surface of the API, but I encourage every developer who uses Github to check out the API and think about how you can integrate it in to your workflow to improve your efficiency.

Add to home screen is not what the web needs. Is it?

There has been a lot of great discussion about standardising the “Add to Homescreen” functionality across browsers.

Before I dive in, catch up with the latest thinking:

We have an obsession with Apps and the deployment models that they present: Upload to a store, drive the user to go to the store, download and install.

Web Developers want installable web apps. They want a place on the homescreen eschewing the need for the (App Play *) model for App delivery. I get it.

We have had this on iOS for a long time via <meta name="apple-mobile-web-app-capable" content="yes"> — if I remember correctly this has been here since the first version of iOS — it was the only way to get apps on to your device. Developers even made promo widgets that let users know they can “install” the web app. Yet it wasn’t enough, developers and users didn’t actually want this, they wanted more capable installable apps. Installing a web page? Are you nuts.

We (web developers) pushed and pushed for installable web apps from the browser even more. It landed in Chrome for Android and developers loved the idea. Not many people have implemented it (even including the Apple syntax). Not many people use it.

When was the last time you added an App to the homescreen? When was the last time you saw any site mention installing a web-app? Thought so.

I am not opposed to making web-apps more integrated with the systems on which they live but we are focusing on the wrong solution to the problem. Ideally you should never be able to tell if you are usage a web page, or using an installed app. But …

No one has made the case that on mobile users want the ability to install web apps to the home screen. Seriously. Apple has had this feature yet users and developers wanted native apps, so they made a new platform whilst solving a huge number of other problems developers were facing that the web never solved: Simple payments and monetisation, better discovery, offline usage (in theory), perfomance and features.

Add to Homescreen is us trying to play in the “apps” league. A league we won’t be able to compete in.

I want to see something much more fundamental. The web offers something far richer: it encourages lightweight usage with no required installation and interaction with on-demand permissions. I never want to see an install button or the requirement to understand all the potential permissions requried before trying the app. The system should understand that I am using an app and how frequently that I use it and it should then automatically integrate with the launch points in the OS.

I don’t have the answer at the moment. Products like Aviate are starting to move to this model. I could have sworn that Firefox OS was doing something similar to this as one facet of their system.

I am goung to write a follow up post about abuse of the “Add to Homescreen” which is an area entirely.

Auto-deploying Jekyll via Github

If you are seeing this then everything worked fine and dandy. Woot.

It probably isn’t hard to tell that this Blog is built using Jekyll (Octopress actually) and one of the things that I have always wanted to fix was how I deploy the site.

The workflow that I have used in the past is to:

  • edit locally.
  • commit changes to a github repository
  • then rake deploy via ssh.

Whilst this flow works pretty well, there are number of times where I don’t have terminal access and even if I did, I don’t have my public keys.

I need to be able to make changes on Github (or any other system that I can use to access my repository) and have them live on my site shortly after.

The new process I have now uses Github’s WebHooks (they are amazing) to tell my blog to pull in the latest changes from the repository, build them and get them live. To integrate with Gihub’s WebHooks I use the amazingly simple Github-Auto-Deploy with some modificiation from the original project and simple build script.

There really isn’t anything to show you other than it just works. Now my deployment process is just a simple push up to Github. I even have the same ability to edit and test locally if I need to.

Hackathons don't win you customers

Oddly I rarely talk about Developer Relations, but I feel like changing that today.

I feel really uncomfortable when I hear people suggest Hackathons are a part of building a sustainable, scalable developer ecosystem.

They are not.

I have run hackathons. Some better than others. I have learnt a lot about them.

Businesses and Platform creators:

  • If you are thinking of running a hackathon to win potential new customers you are doing it wrong.
  • If you are wanting someone to start a business by using your platform at your hackathon you are doing it wrong.
  • If you are running hackathons to raise brand awareness you are doing it wrong.
  • If you are offering winners $SOMERANDOMLARGENUMBER you are doing it wrong.
  • If your product team (PMs through to Eng) are not at the hackathon you are doing it wrong.

Hackathons can be a thing of beauty, they can produce completely unexpected demos, but that is not your goal. You should be using it as a learning exercise for you, your team and fixing your product. It is the developer version of a beta test, not a marketing tool.

Learn from the developers using your platform. Ask yourselves the following questions:

  • Do your demos work? are developers using the demos to build on top of them?
  • Does your documentation work? can developers start by diving into the docs and following the guides step by step?
  • Does your platform work? Is your API intuitive? Are developers getting stuck on certain parts?
  • Is there value to your platform? Is it possible for people to build sustainable integrations on your platform?

You can answer all these questions at a Hackathon. That is what you should be concentrating on.

One little point, rather than just rewarding teams who produce a lot, reward filing bugs and issues on all parts of your product, the apis, the documentation, the demos and the value as well.

Detecting critical above-the-fold CSS

Page Speed Insights for Mobile launched the other week. It’s a tool that analyses your site in the context of a mobile device and tells you what you need to do to improve the network performance of the site.

In about an hour I had taken 3 seconds off my blogs page load time by removing JS files and adding Caching (doh!) and crunching PNGs (double doh!), going from a score of about 34 to 84.

One of the criteria it suggested “Reduce render blocking scripts in ‘Above the Fold’ content”, specifically fixing the blocking CSS. The theory behind this is that the reader should get the first screens worth of content to the user in the first few TCP packets of response. Any script or CSS file that is required to display content within the first screen of content is an additional network which will significantly slow down the apparent rendering of the page.

In my head this makes sense - Critical CSS is the minimum set of CSS I need to make my page look as I expect and readable to the user. Critical CSS in the context of Page Speed Insights for mobile is the Minumum set of CSS required to render the Above-the-fold content. Ignoring whether AtF is really a thing on the web these days, the concept is that often users load the page at the top of the screen and you want to get that set of data to the user as quickly as possible, especially on Mobile where every connection you make to a server slows your site down.

An example follows - the original CSS in this image includes a whole set of features that are not applicable, overriden or are not visible above the fold (if you read a couple of paragraphs down you will see the link to demo). In this code though, the last-child pseudo selector is not output because the content is not visible.

In practice determining what is considered the “Critical CSS” is rather complex. I have one rather huge CSS file that is used for all the content across the site. How do I determine what is critical to that page and what is not?

I have developed a quick proof of concept that will walk your Page’s DOM, and determine the minimal set of CSS. You can fork it on Github or use this code in a bookmarklet or DevTools Snippet. The general flow is:

  1. Iterate across every element in the DOM
  2. Accept elements whose “top” is within the height of window.
  3. Detect the list of styles that currently apply to the element in view using window.getMatchedCSS(node)
  4. Add them to a bucket.
  5. Return the list of CSS.

It works pretty well. If the element is not visible or not on the first screen of content then its matching CSS selectors are not returned in the output.

Possible uses:

  1. Determine the minimum viable set of CSS for a page so you can clean it up.
  2. Integrate into build and testing steps and warn on excessive CSS used on pages. Possibly using PhantomJS
  3. Make it a part of your build to construct the CSS files needed for each page and just the CSS needed for that page.

There are some caveats though.

  1. It only works in WebKit and Blink engines.
  2. It doesn’t know about Media Queries it only determines content based on the current viewport
  3. It will not find the CSS selectors for psuedo elements such as :hover etc.

Another experiment in creating a mobile friendly table of contents

Over the past week I have been working steadily to improve the mobile experience of html5rocks.com. Now don’t get me wrong, it already is responsive, I just don’t think it was hugely readable on a mobile or tablet device.

One of the areas that I have been focusing on is the “Time to first read”, that is how long does it take the reader to get their eyes on the text they want to read. In our case, sometimes it was three screens worth of vertical scrolling before you could start reading the article. The biggest culprit is the Table of Contents (ToC).

Almost exactly a week ago I wrote about experiments to remove the ToC burden. The experiement centred around moving the ToC offscreen and summoning via a user gesture - a tap in this case. My goal was to create this offscreen ToC just using CSS by hijacking the :active psuedo class. Whilst it was pretty easy in my browser of choice (Chrome) it turns out their are inconsistencies amoungst all browser that mean it is nigh-on impossible to create the consistent experience that I wanted.

All is not lost (hence this post).

Our site already had a piece of JS that would toggle a CSS class when the reader clicked the “Table of Contents” header. By using this, it is simple to hang off the relevant CSS styles to implement the table of contents. It uses the exact same principle as the article: Fix the ToC to the footer of the page, when toggled make the content visible. And that is it.

The “con” for this solution is that as of this moment there is a Javascript requirement and I am still trying to work out how to do this purely in CSS.

Given that this is really no different from my previous approach, why am I blogging about it? Well, I just really wanted to show something off.

In speaking with Paul Lewis we looked at the design of the final solution - in my eyes, the ideal solution was to have this small area on the bottom of the page that displays a scrollable ToC. Why? Because as a reader I could still see the content if I wanted to. Paul’s suggestion though was to just take the table of contents full screen.

I was a little sceptical at first (I always am, but Paul is correct 99% of the time). Paul’s suggestion does have the following benefits:

  • Less distraction . The reader wanted the table of contents so give it to them. Having the ToC popup and only take a portion of the screen leaves the user seeing 3 things, the top menu, the article and the ToC. The intent of the reader is not being clearly managed.
  • Less clutter. Scrolling elements in to take up a portion of the screen, but keeps everything else on the screen. There are too many things that the reader could accidentally click on.
  • More screen estate. I did not appreciate this at the time, but by giving the screen up for the ToC we get to do some really nice things that make sense including:
    • Displaying the entire ToC without scrolling in most cases
    • Making the content more readalbe by boosting the font size
    • Creating bigger touch targets through the increased font-size and padding so it is easier to get to the point in the article you want
    • With bigger type we could apply a subtle heirarchy to the content for nested ul by changing the colour of the font sligthly. When the type was smaller it was very hard to see any difference at all in the font colour.

Let’s have a look at the changes.

Before

This is just one example of an article, the header is in place with the title and the author, and then there is a table of contents stopping the reader from starting to read the actual article. Every artcile is currently like this.

After

Now you can see that the header is still in the same place and we can start reading the content straight away. If you want to navigate around the page you can bring up the Table of Contents by clicking the bottom footer.

And as you can see below, the ToC is now a full screen experience, the text is larger and clearer making it easier to interact with.

Overall I am pleased with the new experience and I hoping to get it live soon. The example shown in this article is one of the larger Table of Contents and I think it holds up well even if the user has to scroll through all the headings.

Experiments in buildinig a mobile friendly table of contents

My current focus is on the mobile web. Everything I do need should be to help developers “get” mobile. With this in mind, I was skiming html5rocks on my nexus, and I was struck by the fact that I could not see any content on the first page. Not good.

There are a couple of things that we need to fix on HTML5Rocks when it comes to mobile. Today I am going to focus on the Table of Contents.

The Table of Contents (ToC), depending on the article can be 1/2 a screen in height to 3 screens in height. However you look at the it, you have to scroll to be able to start reading the content. The Table of Contents is also rooted at the top of the document, which on mobile means that I have to scroll all the way to the top to be able to navigate around or understand the structure. Argh.

Just have a look at one of the current articles. Yes the header is too large, but even this small ToC is blocking us from reading the content.

I am working off the idea that if we can get the user to the content quicker, we will improve our read-time, reduce our bounce-rate and create an all-round better experience for developers who read the content we produce.

There are some constraints though:

  1. ToC help you navigate around the page so they need to be visible to the user on page load
  2. Ideally they should always be visible, or easily accessible so you can quickly jump to the parts you need
  3. Due to constraints on the screen size, they should get out of the way as quickly as possible
  4. There should be no rendered-html differences between the mobile and “desktop” versions
  5. If possible use no JS.

With all these in mind I have created my first experiemental ToC. I call it the “Bottom ToC”.

The Bottom ToC is simply a Table of Contents anchored to the bottom of the viewport. When the reader wants to get access to the page structure they simple tap the “ToC” area, it expands into view (whilst keeping them at the same point in their document) letting them select their next reading point. To dismiss the ToC the user can simply clicks back in the main document.

Bottom ToC in its natural state:

Bottom Toc expanded:

It’s not perfect, but I thought it was interesting enough to document.

So, how is it built?

It was a pretty simple build in the end, it required no Javascript and no changes to the rendered HTML. It uses a combination of position: fixed and the :active pseudo class.

Our ToC is structured as a nested set of <ul> elements inside a <nav> element - pretty much how every menu is structured.

<nav class="outline toc">
  <h3>Table of Contents</h3>
  <ul>
    <li><a href="#toc-introduction">Introduction</a></li>
    <li><a href="#toc-topic-sounds">Creating the sounds</a></li>
    <li><a href="#toc-topic-sound">Engine sound</a>
      <ul>
          <li><a href="#toc-topic-looks-like">Looks like this</a></li>
          <li><a href="#toc-topic-go">Give it a go</a></li>
      </ul>
    </li>
   <li><a href="#toc-topic-sync">Getting the sync</a></li>
</nav>

The CSS is simple too. To make it anchor to the bottom of the screen and open when the user clicks on it we do as follows:

.outline.toc {
   position: fixed;
   bottom: 0;
   left: 0;
   right: 0;
   height: 1em;
   overflow: auto;
}

.outline.toc:active {
   height: 5em;
}

That’s it. The important bits are the position: fixed, which takes the element out of the natural flow of the document and anchors it to a defined area in the viewport - in our case the bottom of the viewport. We used the :active psuedo class to manage the opening and closing of the table of contents.

:active is interesting on mobile as it is normally used to style an element with a id that matches the string in the document fragment of the URL (the bit after the #). This is often the case if you click on an anchor that points to an area inside the same document. On mobile browsers such as Safari and Chrome the :active class is also set when you press on any element, which leads to this effect. The really nice thing is that when you click back in the main article, the active element changes thus hiding the menu again.

There are still a couple of isses to resolve so it is not the perfect solution. For example, when the user scrolls up or down in the ToC and reaches one of the extremities the scroll event gets passed through to the parent document.

All in all, I think this is a neat little solution.

Installing Chrome for Android on an emulator

Let me start by saying it is not possible. But I have a half solution.

If you have tried to install Chrome for Android before on an emulator you will be intimately familiar with the series of errors that occur, most noteably:

Arghhh… I am not going to document how you get this far because I will just be spreading alot of useless facts that ultimately lead you nowhere…

The problem stems from the fact that Chrome for Android is only available from the Play Store and is not available for general download. Luckily Chromium is an Open Source project and whilst we don’t have a full Chromium client available we do have access to the Test Shell.

The Test Shell is Chromium without Chrome’s Chrome. It doesn’t look as pretty but it is fully functional as a Browser (minus all the cool stuff such as bookmarking, sync etc). It even includes the ability for you to connect the Remote Debugger to it from your Desktop. Brilliant!

You can find all the recent builds at http://commondatastorage.googleapis.com/chromium-browser-continuous/index.html?path=Android/ and install the builds on your Android device or emulator by running the following command:

adb install [path to the APK you just downloaded]

This is all pretty cool but still a pain. Ideally what you want is a way to quickly install the latest build of the Chrome on Android Test Shell on all the connected devices and emulators. Fortunately, this is possible. The kind engineers on the chromium project have a file called LAST_CHANGE which gives us a pointer to the directory that contains the latest build. With this in hand we can script the entire process.

The following script will determine the latest build of ChromiumTestShell, download it to a temporary file, extract ChromiumTestShell from the archive (into another temporary file) and then install it on your connected devices and emulators.

#! /bin/sh

LATEST=`curl -s http://commondatastorage.googleapis.com/chromium-browser-continuous/Android/LAST_CHANGE`

echo Latest Chromium Android at $LATEST

TMP_DL=`mktemp -t chrome-android.XXXX`
TMP_APK=`mktemp -t chrome-android.XXXX`
REMOTE_APK=http://commondatastorage.googleapis.com/chromium-browser-continuous/Android/$LATEST/chrome-android.zip
 
echo Downlaoding $REMOTE_APK to $TMP_DL
curl $REMOTE_APK -o $TMP_DL
 
echo Extracting ChromiumTestShell.apk to $TMP_APK
unzip -p $TMP_DL chrome-android/apks/ChromiumTestShell.apk >> $TMP_APK
adb install $TMP_APK

And that’s it.

I recongnise that there probably a lot of things wrong with this, so I have made it available for modification and improvement on GitHub - https://github.com/PaulKinlan/chromium-android-installer.