Starting last year, I’ve moved what little on-line writing I’m doing over to Medium. See you there!
When Dion and I joined Palm several years ago during the webOS era, I was very disappointed to learn that we had embraced a second-class public API strategy. While both Palm and third-party apps shared WebKit and a UI library, the Palm-specific hardware stuff was segregated into two APIs: one for trusted Palm developers and another entirely separate set of APIs for the public.
While this wasn’t the root cause of Palm’s failure—that’s another story—it resulted in a comically impoverished API that, for example, didn’t allow developers to vibrate the phone, access the camera directly, or even play audio with any predictable latency (i.e., sounds would play anywhere from 100 ms. to 2000 ms. after you made the API call). This was while developers were shipping amazing, world-changing apps on iOS.
It doesn’t take a genius to understand that in our world of scarce resources and intense competition, such a strategy isn’t likely to result in a robust developer ecosystem. It’s hard enough to keep up with public demand for opening up some of the private API calls; to have an entirely different set of APIs written from the ground up for the public takes the challenge to a whole new level.
When we tried to get the public APIs fixed, engineering managers were sympathetic, but they were constantly making difficult trade-offs with consumer features. They didn’t feel the pain themselves because they had their own private API—and they had plenty of enhancements they needed to make to that one.
More recently, I was reminded of this lesson by examining a very large company’s public APIs for manipulating web-based office documents.
This company is extremely profitable and prides itself on having the best engineers in the world. They point to their high engineering standards and boast about their ability to solve problems that no other company can touch.
I have been using this API on a personal project through a simple wrapper library and have been getting inconsistent results and unanticipated errors. I figured my wrapper library was at fault and that the raw APIs would blow me away with their stability and feature-set.
Well, they did blow me away, in a sense. First, the documentation was atrocious, with one set of docs pointing to another set, which in turn claimed to be deprecated and pointed to a third set, which it turns out covers the APIs for an entirely different set of products.
Bad docs wasn’t a big surprise; this isn’t the first group of engineers to under-document their project.
Fortunately, since this is the web, I can just examine the wire protocol and figure out the gaps in the docs. Except, this company’s web-based apps use an entirely different API than the API exposed to the public. To be clear, both are exposed, but it’s one thing to examine a reference app to fill in holes in docs, and another to reverse-engineer an API from scratch; I have nowhere near enough time to do the latter (and outwit whatever security mechanisms are designed to prevent me from succeeding).
Please, if you find yourself creating consumer products with a public API, do your third-party developers a favor: expose a subset of your internal API; don’t create a new, separate public API.
We talk a lot at Walmart Labs about the large-scale stage we get to play on as the world’s largest retailer. But it’s good to humbled and there’s nothing like Facebook scale to do that to anyone who thinks they have a big on-line userbase. Early this month, it was my pleasure to attend a presentation by Al Urim and Jeff Morrison from Facebook’s mobile web team at Sid Maestre‘s Bay Area Mobile meeting in which they share their experiences maintaining Facebook’s mobile website. I thought they’re be enough interest in the topic to post my notes publicly; hope you find them useful.
The presentation started by re-iterating the numbers Facebook released back in October: they have 604M mobile active users with a quarter of those (126M) being mobile-only over the course of a month. They didn’t break out the number of mobile web users but they did re-iterate their previous statement that their mobile website has more users than their Android and iOS apps combined, which doesn’t clear up the recent contradictory speculative numbers posted by Benedict Evans who claims Facebook mweb is smaller than either Android or iOS. Perhaps the answer is that Facebook mweb double-counts users (e.g., iPhone users tapping on Facebook notification email links and getting to mweb) whereas perhaps Ben Evans’ numbers assume zero sum math.
Regardless, I’m confident we can all agree that this is one popular mobile-optimized website.
One Mobile Site
In mobile, we often talk about the challenges of maintaining native apps and mobile websites in parallel. Facebook had magnified this challenge further by maintaining two separate mobile websites: one for feature phones and the other for modern smartphones. One of the presenters, Al Urim, had some visceral pain from this experience: he had to port the ability to “like comments” to both of these stacks.
To solve this problem, Facebook has unified these two mobile websites into one. To simplify the challenges of coping with diverse mobile device capabilities, Facebook uses an XML-based abstract component framework to encapsulate the details of presentation layer rendering. They shared an example of a button, which they suggested would be written as this in their markup:
(Yep, that appears to be XML namespaces; it’s making a comeback!) That markup is then rendered in diverse ways, such as an <input> on some devices, a <button> on others, etc.
They claimed that this mark-up language covers 80% of the functionality of the mobile site, with the other 20% being custom HTML/CSS/JS code for specific devices. They cited taking advantage of CSS3 features and GPU acceleration as common reasons to write this custom code; there was also plenty of grousing about the challenges of supporting lousy Android Gingerbread-era web browsers.
At this point, the presenters emphasized that their number one priority is moving fast; they don’t tolerate architectures that make it difficult to rapidly iterate on new features. They also enthusiastically endorsed the productivity boost of this approach; it really does take away a lot of the pain of supporting a very fragmented mobile web landscape.
The topic next moved to optimization lessons that they’ve learned:
- Consolidate resources into the lowest number of files you can. Put all your images into image file (i.e., sprits), consolidate all JS into one file, etc. This is pretty standard advice as it minimizes the number of disparate connections required to load images (pipelining notwithstanding) and the cost of establishing a connection on mobile is even higher than desktop. (Incidentally, when I inspected m.facebook.com on my desktop Chrome browser, I saw it actually contains a crap-ton of individual JS files and images. But, when I changed the User Agent to masquerade as a low-end mobile device, I saw the consolidation they were talking about. My guess is that they added special features to support modern mobile browsers and whoever did that didn’t take the time to optimize the specialized JS and other assets used for those features.)
- Caching. Turns out mobile browsers don’t have very useful caches. They indicated their site uses App Cache as a work-around and said they were looking at using Local Storage in the future. (I didn’t see either of these getting used much by their site when inspecting with the browser dev tools, for whatever that’s worth.)
- Manual asset reordering. They talked about manually tweaking your HTML file so that the UI elements and data that the user cares most about will render first and the rest of the page elements can load in asynchronously.
- Use CDNs. Akamai, et al. are your friends! This is especially true for Facebook as their one application is used throughout the entire world. There was a lot of discussion about macro- and micro-latencies (i.e., latency establishing connections to local cell towers versus latency crossing the Pacific). Put your static resources as close to your users as possible. Incidentally, my friend and seatmate at the event, Will Lowry, is a former AT&T exec and shared with me that the connection from the cell tower to the backhaul is a big source of latency as it’s usually just a T1.
In summary, some useful tips but nothing you haven’t already heard if you’ve been paying any attention to Steve Souders throughout the years.
While their mobile site is mostly server-side rendered, they want to increasingly shift to a more client-centric model. Their current approach uses modern frameworks like Backbone and CommonJS/AMD modules to render the chrome of the mobile website on the client and then they request server-rendered content to display within that chrome. Moving forward, they want to explore building out sections of the site to be entirely client-rendered; that will happen in pieces. Older devices fallback to an entirely server-rendered experience; they use WURFL for device detection.
They talked about their desire to move to an architecture that enables seamless conditional rendering of content on either the client or the server; when I asked them for details, they said this was just in conceptual stages. (At Walmart Labs, we’ve been exploring this concept as well; we’ve been calling it “conditional tier rendering.”)
Front-end Team Structure
Their mobile team has structured their development teams into two groups: a core platform team and “product developers”. The core team maintains the framework mentioned above and delivers capabilities to the product developers, who in turn create the end-user experiences. They said they have a very collaborative relationship between the designers and developers; some designers write code, and some developers have a lot of room to implement from high-level design direction.
They also mentioned that they have a dedicated mobile data team that analyzes their massive pile of metrics and help interpret results from A/B tests.
The team didn’t claim any special cure for the QA pain everyone in mobile experiences. They do a lot of manual testing, but they also have some automation: an internal Node.js-based framework that runs unit tests and web driver tests. Their framework-centric development approach helps a great deal too as that core layer is extremely well-tested. They also mentioned a flip-side to this framework goodness: memory management pain. It’s really easy to run into memory issues with two or more components that each try to load large datasets.
There was Q&A, but I’ve mixed in the answers I captured with the content above. Incidentally, my friend Will asked when they were going to open up a Facebook Graph Search API, but they didn’t have an answer (“If you are interested in that, please let us know and we’ll pass the feedback up the chain”).
Kudos to Facebook for sharing some of the details of their web app and stack and for hosting the event. We’ll have to do something similar at Walmart Labs soon.
It goes without saying that mobile’s been a fascinating space to play in over the past few years. It’s also an understatement to say that my views have shifted as the ecosystem has developed.
I started the journey fiercely advocating to the industry and to developers that web technologies should be the lingua franca of mobile apps, both during my brief time at Mozilla and later while I was at Palm as part of the webOS team. Alas, the potential of the web was never realized by the mobile web on iOS and Android and simultaneously the native mobile SDKs exploded in sophistication and richness. Consequently, my views on the role of web in mobile have become… more nuanced.
Dion and I have gone into some detail on these views in various presentations; the next one will be hosted at our Walmart Labs facility close to San Francisco on Tuesday December 4th.
I’m also thrilled to join some of the most influential developers of our time for a panel version of this conversation to be held just two days later as part of PayPal’s TechXploration series down in San Jose. Dion and I will moderate a panel including:
- Abe Elias, founder, CTO and former CEO of Sencha (the ExtJS company)
- Andre Charland, former President of Nitobi (the PhoneGap company, sold to Adobe)
- Jeff Haynie, founder and CEO of Appcelerator (he still writes code btw)
- Steve Yankovich, eBay’s VP Mobile
- David Kaneda, Designer in Residence at Benchmark Capital
I can’t wait to hear what comes out of a conversation with such a great mix of experts on both sides of the issues. Abe, Andre, and Jeff know their tech very deeply, Steve is in the middle of all this with web and native in one of the world’s largest web properties, and David will add a fantastic design perspective. Dion and I have both intellectual and pragmatic interest in the topic ourselves with our roles running mobile engineering at the world’s largest retailer.
I hope I’ll be able to discuss the future of mobile with you in person at one of these two events; come join in and tell me what you think–and let’s help each other evolve our views just a little more.
On Friday, we announced that @WalmartLabs sponsored the Pixate project on KickStarter at the $10,000 level. Today I thought it would be fun to spend a few minutes writing about why I’m personally so excited about this project.
What is Pixate?
Disclaimer: I’m not a member of the Pixate team, but I have spoken with them a bit about the project. Take what I say as unofficial but somewhat informed content.
Pixate brings CSS to native apps. What does that mean? Pixate allows for the customizing of attributes of native UI components using a syntax inspired by the web’s CSS standards. It doesn’t aim to apply every CSS attribute in the various CSS specifications to iOS–that wouldn’t make sense. Instead, its goal is to take the “selectors” part of CSS and introduce attributes and values that make sense for styling native components. Where existing DOM-centric attributes make sense in a native context, they’ll be reused, but where new ones are needed, they’ll be christened as necessary.
Doesn’t CSS Suck for Apps?
Many web luminaries have gone on the record for years talking about how bad CSS is as a visual layout tool. I couldn’t agree more. In my personal experience, CSS layout has been remarkably unpleasant. Despite my years of hands-on web development experience, I must constantly refer to documentation, commentaries, debugging tools, and multiple browsers to achieve any sort of complex custom layout–heck, even simple stuff much of the time. I’m not interested in bringing this sort of thing to native, where the tools are generally better.
However, there is tremendous power in this concept of declarative configuration of user interface components. The parts of CSS that have to do with changing element attributes works quite well–and that’s independent of whether or not the particular set of attributes you have to work with are a mess. The selector syntax is easy to learn and extremely powerful. Editing a few lines in a text file can radically change the appearance of multiple interface definitions and can do so in both very general and very precise ways.
Peanut Butter, Meet Jelly
I’ve long had two feet in the desktop/native app and web app worlds. I started my career doing desktop apps, jumped to web when it hit the scene, came back to the desktop with Java Swing and then tried to bring some of that back to the web by founding Ajaxian.com with Dion and evangelizing rich web clients. As part of this cross-pollination, I created a Java Swing framework that worked a bit like Pixate: it loaded in interface definition files created with a UI builder (in my case, the third-party JFormDesigner app) and then applied CSS rules to the components in those definition files. Despite having different properties than DOM elements, it was an easy trick to expose properties of Swing components to CSS.
I returned to this idea a second time when I was in Mozilla Labs working on Thunderhead, an HTML5 Canvas-based UI toolkit experiment: I implemented part of a CSS engine to theme custom canvas-rendered components.
Based on these experiences, I’ve found that the native + CSS approach works really well. After all, it’s really just a fairly simple labor-saving short-cut. Both iOS and Android apps generally store the user interface as declarative metadata that is instantiated into a UI component graph at run-time. Whereas no one I know modifies this metadata manually in the iOS community, editing this metadata by hand is the standard approach for Android developers. CSS gives both sets of developers a tool to centralize the style-based metadata and to bulk apply styling rules across multiple components (and potentially across multiple screens) in one go. That’s a clear win.
Even if the UI is dynamically generated through hand-coding, the CSS approach can still work. It can be applied before the interface is displayed, and again after it is displayed for dynamic effects.
Update: It’s also worth mentioning that both Adobe Flex and the QT project have incorporated CSS-inspired features into their platforms (thanks to the commenters below for pointing this out).
Why It’s Useful
This approach opens up a few interesting use cases:
- Making it easier to customize a single UI for various different contexts; a more flexible form of conventional UI internationalization techniques
- Making it easier for non-developers to customize the design of native screens. The Pixate team has visions of integrating their engine with Photoshop, etc. Hey, if this happens, great. But allow designers to iterate in the CSS file directly is pretty interesting on its own.
- Creating app prototypes
- Dynamically changing user interfaces after app deployment. A huge advantage of the web over native is the ability the change the UI from the server. By serving the Pixate CSS to the app at run-time, the app’s UI can be changed in interesting ways without an app update. Lots of native developers have hand-rolled their own mechanism to do this, but it’s handy to have a general tool like Pixate for the job.
What Pixate Is Not
Pixate is not, and/or in my opinion should not be:
- An attempt at using HTML/CSS to create native user interfaces.
- An attempt to allow you to reuse web-based CSS files for native apps. The set of CSS attributes that a browser supports will be different than the set that Pixate supports. There may be some common attributes, but I don’t anticipate the overlap will be meaningful.
- A way to develop UIs once for both Android and iOS. I don’t want the Pixate team to waste a lot of time figuring out how to map disparate attributes for kinda similar Android/iOS components into the same CSS attributes. Cross-platform leverage is a non-goal. Let the Appcelerator folks figure out how to map Pixate into the same concepts–in fact, it may make sense to have an Appcelerator-specific grammar for Pixate. That would be really cool.
- Some kind of cross-platform development toolkit that blocks developers from developing their native apps the same way they always have. (Sure, developers will have to make some minor accommodations to incorporate Pixate, like including the lib and perhaps occasionally giving UI components a unique identifier.)
- A silver bullet. Sometimes it doesn’t make sense to apply static, declarative CSS to a native UI. That’s okay.
Furthering the State of the Art
I believe that we should support innovative tools creators in our industry. When projects come up that represent interesting attempts to further the state of the art, I try to be one of the first ones in line to buy licenses and support the projects, just like many other folks I know. I’m proud that ‘Labs has been able to sponsor Pixate so generously.
And perhaps it goes without saying, but in case it doesn’t: we’re always looking for great talent and we’re doing some really cool things in on-line and in-store commerce. Drop me a line (beng@walmartlabs…) if you’re interested in joining us.
28 August ’12 Update: Made some minor grammatical corrections and added the Flex / QT mention above.
When it was announced at this year’s Google I/O, the Nexus Q team took pride in the fact that people upon first observation generally had no idea what to make of the device. After playing with it myself for a couple of days, I’m not sure what to make of it either.
It all started well-enough, as I attested to in my recent tweet:
Really impressed by seamless Nexus Q setup and integration with Jelly Bean. Not happy. Life was simpler when iOS was clearly better. 😉
Big bonus points to Q for simplifying the typically tedious wireless network setup process (it uses Bluetooth to send your wireless network config and just requires you to re-enter your password via your Android mobile device). A clear win over Apple TV–and any other consumer device with a remote control I’ve used up to now.
But all that’s mitigated by the physical setup process. Now I have this weird ball–with cables that prominently protrude from its back-side–on top of my entertainment cabinet. The Q team gleefully bragged about their breakaway from boring boxy shapes, but where am I going to put the thing? Sorry, not in the middle of my living room. Whether intended or not, thanks to those cables, it’s going in my entertainment center, like all other devices of its class. Except, unlike the others, it doesn’t fit well, thanks to the awkward aforementioned shape. Hmm.
It turns out avoiding streaming from the phone is a great strategy for streaming from the cloud. So nice to tap the Nexus Q playback button strewn throughout Jelly Bean and have the device quickly start streaming music, YouTube movies, and so forth. Makes iOS seem positively backwards for streaming from the Internet to the iOS device and then from the device to the Apple TV for the same use cases; surely Apple will put in a fix in a subsequent version that identifies when a command to the Apple TV should be sent instead of a media stream.
But the Q’s strategy falls flat on its face since it’s the only strategy employed. I went to stream music from the Pandora Android app to the Q, but of course, that’s not going to work. Oof. And Q doesn’t have any support for my media: my photos, my videos on the phone, etc.? Ugh.
Q plays a standard, circa 2000 WinAmp-esque visualizer when music is playing. My kids find this so incredibly cool. I was a little shocked. I’d sort of forgotten about visualizers. Now, seeing how gleefully they dance and stare at the TV, I wish I had them in the Apple TV.
But streaming video doesn’t seem to work all that well on the Q. I streamed a 45 minute TV show on my Apple TV, using my Samsung receiver’s Vudu app, and using the Nexus Q. Only the Q had any trouble doing it at full HD. And what trouble it had! Eight “loading” pauses–one of which was really long–during the first five minutes of the show. I switched from the Q to just streaming it on the Nexus 7 tablet; after one such pause, it played back without further interruption. It was just the Q that struggled. What a bummer.
The hardware mute switch (i.e., pushing the ball) works great! Love having that. So much better than fishing for a remote to pause the music on the Apple TV.
And then there was my wife’s reaction when I explained to her we couldn’t play back any of our iTunes music on the Q: “What? Oh, that sucks.” It really does suck to have digital media so stove-piped into all of these different proprietary networks. Google is so late to the game here; how many of us are going to start mixing our media across Apple and Google? I don’t think I will–despite Google bribing me with $25 to give them my credit card. I wonder if that’s for bragging rights as much as a bet that I’ll spend >$25 buying media.
So what to make of the Q? Like so many others, I’m left scratching my head. High-production values have gone into this thing (with the exception of the UI in the Q’s Android-based setup app), but it’s not competitive with the Apple TV and it’s triple the price. The software can be upgraded, of course, so it’s hard to get too worked up over the software-specific issues–but then there’s the question of the hardware.
Am I really going to buy a few of these at $300 a pop and distribute them throughout my house? No, I’m going to just have one hooked up to my TV. And if I do that, why include an amp? I’m just going to run it through my receiver. The built-in amp just seems so weird to me. Is it an attempt to justify the big price? Or does Google really think they’re tapping into a big market opportunity?
And then there’s the question of Google TV vs. the Nexus Q. Are they expecting us to buy two TV-connected devices? Or use Google TV for your TV and the Q is just for music throughout the house? At $300 without speakers? Back in iOS-land, I balk at the thought of spending $300 for nice AirPlay speakers. At least with AirPort Express units throughout your house for streaming music everywhere, you get crazy-good Wifi coverage as a bonus and plenty of places to tether USB devices, too. Good luck with this strategy, Google.
I’m just so confused on so many counts.
But one thing is very clear: after initial concerns about where to put the thing, I’ve decided that it’s fun to have an exotic, alien-esque orb glowing under my TV.
Post updated on 7/1 with a note about Pandora streaming and other minor changes intended to clarify various points.