The KISS Principle

The KISS Principle states that most systems work best if kept simple, avoiding unnecessary complexity. By applying this idea to the Hootsuite App Directory, we were able to make a massive difference in speed and functionality, while simplifying the overall process.

What is Hootsuite’s App Directory?

Hootsuite’s App Directory is a program for 3rd party developers to build apps and integrate them into Hootsuite web dashboard. We currently have over 100 apps in the App Directory, including popular apps like YouTube, Tumblr, Mailchimp and WordPress.org. These apps not only extend the dashboard’s functionality, but also provide great value to our customers.

App Directory SDK

From an engineering point of view, an app is essentially a web page embedded in the dashboard. It has its own UI and is hosted on a 3rd party server, which means the domain of the app is different from that of the Hootsuite dashboard. It can be somewhat tricky to communicate between the two using front-end Javascript because of the same-origin policy, so to facilitate this, we introduced the first version of the App Directory SDK the same time we launched the App Directory program.

How Does it Work?

The App Directory SDK is a set of Javascript and HTML files that help to work around the single origin policy and allow cross-domain front-end two way communication between the Hootsuite dashboard and its apps.

v0.6 SDK Workflow
v0.6 SDK Workflow

The above graph illustrates the workflow of the SDK before the improvement. The grey boxes represent pages in Hootsuite’s domain, and the blue boxes represent pages in an app’s domain. hsp.js is the Javascript SDK file the developer needs to add in the app page. It provides a rich range of endpoints the app can use to interact with the dashboard, such as sending a message, opening a popup, etc.

Below is a flow for an app to open a popup on Hootsuite dashboard:

  1. The app calls the hsp.js endpoint: hsp.showCustomPopup()
  2. hsp.js appends an iFrame inside the app page. This iFrame loads a “receiver page” that is hosted on Hootsuite’s domain. It listens to any changes happening to the iFrame URL hash fragment.
  3. hsp.js then changes the iFrame URL hash fragment to something like #showcustompopup
  4. Receiver page notices the change, and it realizes hsp.js wants to open a popup on Hootsuite’s dashboard. Because the receiver page and Hootsuite’s dashboard are in the same domain, the limitation of the same-origin policy doesn’t apply.
  5. Receiver page fires a function call to the receiver js in Hootsuite’s dashboard
  6. Receiver.js receives it and opens the popup in the dashboard

Repeat these steps in reverse for the dashboard to communicate back to the app.

The Problem

Although the workflow is a little complicated, this SDK actually worked pretty well for a few years. However, when our customers started to add multiple apps on the dashboard and apps themselves became more complicated, we experienced problems with performance. Complaints and bug reports came in from more and more customers, saying that app events were not firing, or that app plugins were disappearing entirely. We quickly found that the problem was due to the gateway “receiver page” only being able to handle one hash change at a time. If events are fired simultaneously, some events will override others. Later observations showed that Chrome stops to handle those events properly, at the rate of 10 events/sec. This bottleneck encouraged us to rethink the SDK and look for a better solution to cross-domain communication.

The Solution

After few weeks of research, we found our solution: the native JS method Window.postMessage(). This method safely enables cross-origin communication, packaging a message in an object (string in IE 9 and earlier) and sends it to the target window. The target window can simply listen to the message event to get the message, while a whitelist for allowed domains can be configured on both sides to ensure the security.

Streamlined v2.0 workflow
Streamlined v2.0 workflow

The above graph illustrates the workflow of the new SDK using postMessage(). The green boxes are the new improved Js files. As you can see from the graph, the architecture is much, much simpler than the previous SDK after removing the “receiver pages”.

Now, if an app wants to open a popup on the dashboard:

  1. App calls hsp.showCustomPopup()
  2. hsp.js sends a “message” to its parent window (Hootsuite dashboard)
  3. receiver.js receives it and opens the popup
  4. Reverse it for dashboard-to-app communication

The 100X Result

Not only is the new SDK simpler to understand, it fundamentally removes the performance bottleneck we suffered with the old SDK. Thanks to the changes we made, the new SDK can now handle events firing at 1000 times/sec: exactly 100 times faster than the old SDK.

Rolling Out

Researching, verifying, implementing, and testing the new solution is a big task, but rolling out the new SDK is another challenge on its own. We have more than 100 apps using the old SDK, and we want to quickly convert all of them to use the new SDK. Therefore, at the start of designing the new SDK, we decided to make the new SDK 100% backwards compatible. First, we kept all the publicly facing endpoints of the old SDK unchanged, from their names to the parameters they take. Then, we carefully changed the mechanisms underneath and decoupled the endpoint and communication layers. After this was done, we tested it and replaced the old “iFrame hashing” communication layer with the new “postMessage” communication layer. The final result: our developer can update their apps by simply replacing the hsp.js with the new one, and that is it!

For our app developers, it took just a single step to make the app 100 times faster!

If you’re interested in our App Directory program, you can visit:

About the Authorimage02

Joe Ying is a Software Engineer in Hootsuite’s App Directory team. He moved from Shanghai to Vancouver 10 years ago, and enjoys the superb natural setting of Vancouver. When not coding, Joe likes to hike in the summer and snowboard in the winter. Follow him on Twitter @JoeYing_1986.