Making Facebook's native mobile app faster using HTML5(sencha.com)
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.
We do a side-by-side comparison of the native Facebook app and our Sencha Fastbook app.
So the Fastbook app is the first to make use of a brand new “Sandbox
Container” which programmatically detaches complex views and renders
them into their own iframes, and thus partitioning the DOM tree. This
special container doesn't need any extra handling at the application
level, so it's seamless to developers (i.e., any component added to this
container will be sandboxed automatically). But it does come at a cost:
events, positioning, styling, and JavaScript code have to be proxied
between the parent window and the child sandboxes. This is complicated,
so without a robust and properly architected framework, it is very
difficult to implement. Sandboxing allows layouts to be isolated, and
therefore keeps the primary DOM tree as light as possible. To bring
balance to the Force, Sandbox Containers must be used wisely.
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.
Bonus Points
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.