Earlier this year, Mozilla reached out to Facebook with an exciting project they had been working on in Mozilla Labs. The concept was to build an API that would allow social mediums to integrate content directly with the browser. Facebook was a natural early partner, having a mature chat product as well as lots of dynamic content in the ticker and sidebar. Mozilla built out the SocialAPI to enable a series of new features to make the experience feel truly integrated, including embedded jewels, ticker stream flyout panels and browser-provided chat tabs.
One of the great things about building the product directly for Firefox 17 is that we could take a dependency on a number of HTML5 standards, such as WebSockets and Shared Worker. This allowed us to architect our messaging stack from the ground up to be fast and efficient.
Using HTML5 WebSockets
Historically, web developers have worked around the limitations of web standards by polling servers for updates via asynchronous requests. These asynchronous requests are somewhat expensive because the client-server has to perform some handshaking on each poll. HTML5 introduces a new API, WebSocket, which addresses these issues by keeping a client-server connection alive and only requiring the hit of handshaking at the time of opening the connection.
Messenger for Firefox is the first Facebook product to use WebSockets at scale. We rely on our existing chat servers, and added the ability to handle WebSocket connections. On top of that we use the MQTT protocol, which we already use in the mobile Messenger apps and in Messenger for Windows to communicate with our chat servers while consuming less bandwidth.
Using HTML5 Shared Worker
In our first standalone chat product, Messenger for Desktop could rely on assumptions such as having at most one instance of the product open at any given time, and being able to create invisible windows which could perform data fetching without rendering until necessary. In Mozilla’s SocialAPI, however, the notion of invisible windows was replaced with an implementation of the HTML5 Shared Worker. This worker provides a mechanism for communicating and synchronizing across the different content elements for the product.
Messenger for Firefox is able to take advantage of having a centralized location to fetch data asynchronously and synchronize the state across the user’s Facebook notifications, friend requests, messages, ticker stream and chat tabs without duplicated fetching.
One of the challenges we encountered was using existing Javascript code from within the context of a DOM-less Shared Worker. Many of our libraries take a dependency on being able to access DOM elements. At Facebook, every developer is empowered to make changes to libraries and existing code. We were able to tweak all of the libraries that Messenger for Firefox takes a dependency on and remove the libraries’ assumption of having access to DOM elements, allowing us to reuse well-built and tested code from the Shared Worker.
Our ability to work with a small team and push code on a daily basis meant we could rapidly iterate on the API design and feature work to get this integration into the wild. It has been awesome getting to work with the latest and greatest HTML 5 technologies as well as the talented developers at Facebook and Mozilla.