The Making of Fastbook: An HTML5 Love Story
When we started what became Sencha, we made a bet on the web: a bet that modern application development didn't need anything except the browser, a great set of frameworks and a great set of tools. With those three weapons in hand, we knew developers could build applications that would delight users. The advent of HTML5 upped the game and it gave developers even more tools to let them treat the browser as an application development platform and not a page rendering engine. Developers sprang at the opportunity and unleashed a torrent of apps — on both desktop and mobile — that leveraged the new HTML5 capabilities to build amazing applications using web standards.
So, when Mark Zuckerberg said HTML5 wasn't ready, we took a little offense to the comment.
We thought to ourselves: HTML5 can't really be the reason that Facebook's mobile application was slow. We knew what the browser on modern smart phones was capable of and what kind of rich capabilities HTML5 offered. We saw the latest generation of mobile devices — running at least iOS 5 or Android 4.1 — push ever increasing performance and HTML5 implementation scores. But perhaps most importantly, we'd seen what our customers were building and the amazing things they were creating using HTML5.
“So, when Mark Zuckerberg said HTML5 wasn't ready, we took a little offense to the comment.”
We had our suspicions about why Facebook's mobile application team had problems, because it matched a common pattern. At Sencha, we build frameworks and tools for application developers, so we have pretty deep experience with development teams taking on HTML5 app projects. When a team has problems with HTML5, it usually stems from the fact that they take a “website” development approach to building an app, and often don't use the right tools and architectures for application development. This is what we suspected about the Facebook HTML5 app. The way that app performed — slow loading, choppy user experience in the News Feed, low framerate — exhibited the usual symptoms.
In any event, we knew HTML5 was, in fact, ready, and we wanted to prove it. So we took it upon ourselves to rebuild the challenging parts of the Facebook mobile application in HTML5 in our spare time. Today, we'd like to introduce you to Sencha Fastbook, a technology proof of concept that shows how fast HTML5 can be, and demonstrates how readily HTML5 can be used to handle the toughest app challenges.
Learn the latest about Fastbook and the tech behind it at SenchaCon 2013. Register today!
This four-minute video gives you a quick overview of Sencha Fastbook, and shows you a side-by-side comparison of how well our HTML5 app performs against both the native iOS and the native Android Facebook apps (versions 5.2 and 1.9.12 respectively, the latest available when we made this video on December 10th). The rest of this post gets into the technical details of how we built Fastbook.
A Closer Look at the “Native" Facebook Application
We started the process of what became Fastbook by trying to understand the Zuckerberg claim that HTML5 “just wasn't there”, and the best place to do that was to take a deep look into the latest native Facebook app on iOS. We connected an iPhone to a web debugging proxy, and started to look at the HTTP traffic the application pushed over the network. Our biggest shock: much of the application was still raw HTML pages. The News Feed had moved to native as had the profile page, but many of the other application UIs were simply HTTP GET requests to m.facebook.com. Today's “native” Facebook application is a hybrid web / native application: there is content rendered on m.facebook.com and displayed in a UIWebView and native Objective C components mixed together.
Re-Implementing the News Feed
After we looked at how the native Facebook application worked, it was clear to us that the hardest part of the experience to build was the News Feed. Dealing with a billion content creators posting an unlimited amount of content in a completely unpredictable manner is a tough problem to solve even for the most seasoned developers, regardless of what technology they use.
We really wanted to ensure we had that smooth experience the News Feed should deliver when we re-implemented it in HTML5. To make that possible we added some new features and enhancements into the core of the current Sencha Touch framework.
It started with the implementation of an Infinite List Component that handles items with unknown sizes. Only a very small set of DOM nodes is actually created to fill in the actual visible screen area. They will then be constantly recycled to render next / previous data on-demand. As a result, memory footprint is kept minimal, regardless of the amount of data in the Store. Making this work is the easy part. Making it fast with the complexity and variety of items such as News Feed stories is the real challenge. The bottleneck lies within the core processes that a browser has to perform: layout and compositing.
Our experience with building frameworks has taught us that while a small demo component might work well on its own, it often then performs poorly when put into a much larger app. As an app grows, the DOM tree grows; and as the DOM tree grows it takes longer for the browser to calculate the layout, and the performance degrades. Moreover, as the number of visible layers increase, compositing performance for each layer also degrades dramatically. We needed a solution to make web apps more robust under large numbers of DOM nodes.
For Fastbook, the News Feed, Timeline and Story views are individually sandboxed. Since all DOM elements are re-used to render data on-demand at high frequency, reflows are inevitable. The key is to make that process as cheap as possible. Sandboxing enables the News Feed to perform as if it is standalone, while actually is still a part of the much bigger DOM tree.
“Sandboxing enables the News Feed to perform as if it is standalone, while actually is still a part of the much bigger DOM tree.”
Next, we added deeper integration to our TaskQueue, a feature we recently introduced into Sencha Touch. TaskQueue prevents the interleaving of read and write requests to the DOM, eliminating any unnecessary layouts. This, combined with the new sandboxing technique, significantly reduces costly layouts from complex views such as the Timeline and News Feed.
We then added the AnimationQueue, a new class that's responsible for all animations and events, as well as scheduling heavy tasks for later execution during the CPU's idle time. It acts as the framework's traffic cop, prioritizing different operations and helps ensure the application stays responsive. When an app is animating, it suspends lower priority functions. When the app is idle, the AnimationQueue executes the suspended tasks. For example, while scrolling the News Feed at high speed, image loading and rendering is suspended until the app is idle in order to increase the scrolling performance. Additionally, heavy tasks are released gradually in a non-blocking manner with a high-speed timer. This ensures touch events always have a chance to be handled as soon as possible.
On the other hand, there are some classes of functionality that you don't want to suspend, such as getting more data to feed the list. To help ensure this doesn't slow down scrolling, we use Web Workers. These allow us to move XHR/RPC communications away from the UI thread. Saving network request cost and JSON encoding/decoding using Web Workers makes great use of today's multi-core devices.
Those are the major points of what we did to bring Fastbook to life, and what allows it to perform well with pure open-standards based web technologies. It's exciting for us to be able to show how you can leverage all the features of HTML5 to build an app like this.
One of the interesting things we found while investigating network performance of the native iOS Facebook app was that the API calls returns huge amounts of raw data to the client. A typical example is API calls made to https://graph.facebook.com/graphql/ to render News Feed items. In average, 15KB to 20KB of gzipped JSON data is transferred for every 10 items, much of that is not needed to render the actual views.
To demonstrate what could be done to optimize network transfers, we put a proxy server in place to clean up and parse the raw data returned from the Facebook FQL API. As a result, Fastbook transfers far less data than the native app to render the same views: as little as 10% to render the same items on the News Feed. The proxy also allows us to offload some of the more mundane tasks such as content formatting and filtering to the server-side.
Also, you may notice a difference in the scrolling deceleration time between the native iOS app and Fastbook. In the native app, scrolling doesn't stop for about 3s. We decided to increase friction and reduce the animation duration to 1.4s. This not only makes content ready to read faster, it also provides extra idle time for the app to buffer more items while the user is still reading existing content.
Try It Yourself
Fastbook isn't a replacement for the Facebook application. It's a technology demo that shows what developers can do with HTML5 if they take the right approach, and use the right frameworks and tools. If you've been wondering if HTML5 is ready, try Fastbook for yourself on a modern smartphone (we recommend at least iOS 5 or Android 4.1). You'll see that when you treat the browser as an application platform and leverage the features of HTML5 that even the most sophisticated applications can be made with HTML5.