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.