Biz & IT —

A behind-the-scenes look at LinkedIn’s mobile engineering

Pros' network was anything but in the mobile space. Then ethos and execution linked up.

Building a hybrid app with HTML5 and native code

LinkedIn uses a combination of HTML5 and native code in its user interface. Prasad told me which technologies they use for various parts of the app and gave me a detailed explanation of how LinkedIn has made the two approaches interoperate.

Prasad says that HTML is very effective at rendering what he calls “detail” views, large blocks of informational content consisting largely of rich text and graphical media. The flexible layouts offered by HTML make it useful for such usage scenarios, but there are also major areas where LinkedIn chose to use native controls. Why? Prasad said Web technologies weren’t entirely up to the task.

Prasad dismisses the idea that you have to choose between native controls and HTML, saying that it represents a false dichotomy. Ultimately, LinkedIn’s iPhone application consists of 70 percent HTML and 30 percent native.
The biggest example he cited of an area where HTML5 still falls short as a user interface layer for data-driven mobile applications is in displaying long lists of content. He said that native widgets are needed in order to achieve smooth and seamless scrolling for list displays with hundreds or thousands of items. Attempting to display such lists with HTML and JavaScript proved impractical. Prasad saw this as especially true for “infinite” lists, where new content is fetched dynamically and appended to the bottom as the user scrolls.

When implementing an infinite list, you can’t just keep adding items to the bottom. Memory overhead quickly becomes unacceptable unless you also simultaneously pull items from the top after the user has scrolled past. Prasad explained that manipulating the HTML DOM (Document Object Model) during scrolling caused some stuttering.

It’s hard to measure exactly what is going on when that happens, but LinkedIn guessed that page layout computations or JavaScript garbage collection were sapping too much of the device’s limited resources. On top of the performance issues, Prasad felt it was exceptionally difficult to implement kinetic scrolling in HTML that felt truly native across platforms.

It’s worth noting that rival social network Facebook raised very similar concerns about list performance and scrolling in a recent message to a W3C mailing list. Facebook largely ended up swapping HTML for native user interface controls in the latest update of its own mobile application.

For Prasad, however, the limitations of current Web rendering engines don’t demand a full return to native code—it’s a matter of using the right tool for the job. He dismisses the idea that you have to choose between native controls and HTML, saying that it represents a false dichotomy.

Ultimately, LinkedIn’s iPhone application consists of 70 percent HTML and 30 percent native. The Android application is roughly 40 percent native and 60 percent HTML. The Android application relies more extensively on native elements because the platform’s HTML rendering engine isn’t quite as capable as the one on iOS.

LinkedIn had started with an 80-percent-native Android application, but has been able to gradually increase the amount of HTML over time due to incremental improvements in the platform’s HTML renderer. Prasad is hopeful that the greatly enhanced HTML renderer that comes with Chrome for Android will eventually be available in the embeddable HTML display component that Android supplies for third-party applications. He described Chrome for Android as “awesome” and said that its support for hardware-accelerated rendering is great.

Aside from handling some performance-critical user interface elements like lists, the native part of LinkedIn’s application also serves a vital role in trapping and responding to errors uncovered in the embedded HTML views. In cases where an embedded HTML pane encounters a fatal error, the native part of the application can cleanly bring it down and then repopulate it, often without the user even knowing.

Prasad briefly discussed his views on Web runtime solutions, such as PhoneGap, that aim to simplify HTML-based mobile application development and provide such applications with native shims to underlying platform functionality. While PhoneGap and similar frameworks are useful for rapid prototyping and for companies with limited resources, he said, it’s better to implement the native parts of hybrid mobile software in a way that meets the specific requirements of the individual application. Ideally, he told me, developers should choose the right balance between native and Web for each application and then build their own bridge between the two environments.

I asked him to describe the specific mechanism he uses on each platform to enable communication between native code and the HTML user interface elements. On Android, the LinkedIn application largely relies on the platform’s built-in support for exposing specific Java functions into the JavaScript runtime of an embedded HTML view. That feature made it relatively straightforward to bridge the gap.

On iOS, the matter is a bit more complicated. He said the company tried several different methods before settling on one they felt was most effective. Their first approach involved using a platform API to “eval” JavaScript expressions in the embedded WebView. This proved to be too computationally expensive, sometimes introducing undesirable jerkiness.

The second approach that LinkedIn tested was one using WebSockets to establish a connection between the HTML components and native code. This worked exceptionally well from a performance perspective, but wasn’t stable enough for practical use. LinkedIn used this method in an actual release, but later replaced it.

Finally LinkedIn tested, and ultimately chose to adopt, something surprising. The company embedded an extremely lightweight HTTP server in the application itself. The HTTP server exposes native functionality through a very simple REST API that can be consumed in the embedded HTML controls through standard JavaScript HTTP requests. Among other things, this server also provides access to the user’s contacts, calendar, and other underlying platform functionality.

When I asked Prasad if this approach raised any security issues, he said that the company reviewed it internally and found it to be acceptable. There are a number of precautions that are taken in the application to prevent it from being abused. The server is bound only to localhost and can’t be accessed by other devices on the network. It also suspended immediately whenever the LinkedIn application is sent to the background.

LinkedIn's app on a second generation iPad—demonstrating the relaunch focus on speed, simplicity, and reliability.
LinkedIn's app on a second generation iPad—demonstrating the relaunch focus on speed, simplicity, and reliability.
Nathan Mattise

Building a more scalable backend

When LinkedIn was deciding how to rebuild its backend, the company used a similar philosophy to the one that had directed the application design decisions. Like everything else, they wanted their backend technology stack to be fast, easy to work with, and reliable.

In a large-scale backend system, Prasad said, companies typically adapt the traditional model-view-controller (MVC) pattern into a three-tier system. The bottom tier consists of the database storage layer, the middle tier handles caching and some business logic, and the top tier serves as the presentation layer, generating your HTML views.

When you are building a mobile application, he said, this structure is no longer applicable. Your presentation layer is on the device itself, often consisting of native user interface elements. LinkedIn wanted a new kind of middle tier that would facilitate more effective communication with a mobile frontend.

In order to minimize the latency introduced by establishing new connections, the LinkedIn developers decided the application should establish as few connections as possible with the server. This led them to a model where the application is essentially piping all of its data through a single connection that is held open for as long as it is needed.

The client application connects to a system on the backend that functions as an aggregator, pulling together all of the data that it needs from various components of the backend stack and combining it all into a unified stream of data that can be piped down to the client application through a single open connection.

To build this streamlined middle tier, the LinkedIn developers wanted to use a lightweight event-driven framework. They also wanted an environment that would be well-suited to handle the aggregation and string interpolation capabilities required for the service. They tested several candidates, including Ruby with EventMachine, Python with Twisted, and the JavaScript-based Node.js framework.

They found that Node.js, which is based on Google’s V8 JavaScript engine, offered substantially better performance and lower memory overhead than the other options being considered. Prasad said that Node.js “blew away” the performance of the alternatives, running as much as 20 times faster in some scenarios.

Another advantage of adopting Node.js for the project is that it allowed LinkedIn’s JavaScript engineers to put their existing expertise to use on the backend. Prasad said the company was able to combine its frontend and backend mobile teams into a single unit. The event-driven nature of frontend development made it easier for the user interface programmers to understand the way that Node.js works.

Prasad was practically giddy when he told me just how much the transition from Rails to Node.js improves the scalability of LinkedIn’s mobile backend infrastructure. Impressively, the company was able to move from 30 servers down to three, while still having enough headroom to handle roughly ten times their current level of resource utilization.

Firefighting scalability problems on the old infrastructure had been a major distraction, one that forced the company’s engineers to spend a lot of time just keeping the system running. With that problem defeated, the engineers were free to spend more time focusing on user-facing product improvements.

Perfection is elusive

The mobile engineers at LinkedIn have done some impressive work to make the application fast, responsive, easy to use, and aesthetically pleasing. But reliability, the third item in LinkedIn’s taxonomy of mobile priorities, remains an issue for some users. LinkedIn’s iOS application currently has an average rating of two-and-a-half stars out of five, with an average of three stars across all versions. The Android application fares a bit better, with 3.7 stars out of five. LinkedIn rolls out routine updates as it continues to improve its software.

LinkedIn’s mobile application has also been the subject of privacy concerns. It faced scrutiny earlier this year when security researchers discovered that it was programmed to send user calendars back to the LinkedIn mothership. The company responded by tweaking this behavior and attempting to make it more transparent to the end-user.

But ultimately, building a mobile experience for a popular social network is not an easy task. Whatever shortcomings currently exist are being monitored, and could potentially be addressed in the same way this redesign built on past feedback. Prasad’s description of the underlying technical details not only offers a glimpse into the challenges and complexity of this problem space, but he provides unique insight. When you experience LinkedIn mobile now, you're experiencing the company’s engineering culture and the philosophy that guided its design and development process.

Channel Ars Technica