Tuning Add-on Performance: Windows Live Messenger Companion

Since we released IE9 Beta we’ve received lots of great feedback on the Add-on Performance Advisor. It’s encouraging to see how users are able to stay in control of their browsing performance in IE9. Ultimately, we want to enable users to use more of their add-ons without negatively impacting performance. To that end, we dedicated many of our recent posts to providing guidance to add-on developers on how to measure and improve add-on performance.

Our internal partners have focused on making performance optimizations to their add-ons based on the guidance we provided. A great case study is the Windows Live Messenger Companion add-on. You can learn more about their engineering efforts in the guest post below.

- Herman Ng

As we blogged here, Windows Live Messenger Companion is an add-on for Internet Explorer that ships with Windows Live Essentials beta.  Messenger Companion allows users to discover links that have been shared with them on their various social networks while they browse the internet.  Enabling the key scenarios for Messenger Companion requires the add-on to listen to various browser navigation events and run operations like network calls.  These operations can be expensive and affect the user’s browsing performance.

To present shared links to the user, Messenger Companion listens to the browser’s NavigateComplete2 event.  It then queries its servers for shared links that match the domain the user is currently visiting.  If a match is found, Messenger Companion presents a notification to users telling them about the new shared link.  If users click on the notification, Messenger Companion shows a rich preview of the shared links on the domain.

Some popular domains, like YouTube.com, can have an average of 40 or more shared links at any given time.  Displaying a large number of items can slow down the browser since rendering the list must occur on Internet Explorer’s UI thread.  To address this issue, Messenger Companion only loads and displays two or three shared links at a time.  When users page through the shared links, Messenger Companion updates its UI to show the next set of shared content.  This is an example of how an on-demand architecture can greatly decrease the performance hit that add-ons have on Internet Explorer.

The different events Messenger Companion listens to are BeforeNavigate2, NavigateComplete2, and DocumentComplete.  The following table describes the operations Messenger Companion completes at each event and the steps the Messenger Companion team took to minimize the add-on’s performance impact on Internet Explorer in terms of both load time and navigation time:

Internet Explorer Event

Operations

BeforeNavigate2

- This is the event where Messenger Companion does the least amount of work so that it doesn’t delay navigation - Messenger Companion clears its internal state for the current navigation - If Messenger Companion’s UI is open, it is closed

NavigateComplete2

- Messenger Companion starts some URL-based processing.  The processing includes querying our servers to get the shared content and detecting whether or not the user is signed in.  These expensive operations are run asynchronously on a background thread and Messenger Companion unblocks the UI thread as soon as possible to prevent any delay to Internet Explorer - To prevent unnecessary operations, Messenger Companion only listens to the main browser’s NavigateComplete2 event

DocumentComplete

- If Messenger Companion needs to show any UI, it is displayed on this event - The work here is minimized so that Messenger Companion doesn’t delay the page rendering

To minimize Messenger Companion’s impact on Internet Explorer’s startup and tab creation performance, the add-on uses a couple of strategies:

Strategy

Details

SetSite() optimization

- Messenger Companion returns as quickly as possible when SetSite() is called.  To do this, Messenger Companion delays all of its work until after the first NavigateComplete2 event is fired by the browser - Messenger Companion only uses SetSite() to cache the pointer to the browser and create its internal service provider - All long-running operations on shutdown (SetSite(NULL)) are moved to Messenger Companion’s elevated process.

Delay the creation of Messenger Companion’s elevation process

- Messenger Companion creates its elevated process only when it’s needed - This enables Messenger Companion to play nice with the rest of the processes by not running its process unless the user actually uses its services

Elevated process optimization

- All requests from the add-on to Messenger Companion’s elevated process are handled asynchronously to minimize the time the add-on has to wait for a response - Messenger Companion’s user elevation helper is designed as a multi-threaded apartment (MTA) process so it can handle requests from multiple instances of the add-on

External dependencies optimization

- When Messenger Companion loads external DLLs, it uses a delay load model.  This means that the DLLs are not loaded directly when Messenger Companion’s DLL is loaded.  Instead, Messenger Companion explicitly loads them when it needs them using the LoadLibrary APIs. This improves Messenger Companion’s DLL loading time

When measuring Internet Explorer add-on load or add-on shutdown times, great care is taken to produce trustworthy, repeatable and accurate results. In general, during performance improvement iterations, the Messenger Companion team took the following steps to arrive at their performance goals:

Include detailed instrumentation in and around key functions

  • Calls to resource-intensive functions; functions that are called repeatedly; and functions writing to disk or performing network operations should be high-priority targets for measurement. Use a profiling tool to discover these functions and measure them accordingly – in many cases it was found that a single function call was responsible for 90% of the elapsed time of a user operation
  • Treat function calls to external partner code as your own – the Messenger Companion team measured function calls to shared partner code and found performance issues that directly affected our product and others

Decrease variance in measured elapsed times

  • Reduce “noise” in the measured results by eliminating all unnecessary background processes during a performance run, and by averaging many measurements of the same test. Run statistical analysis on the results to identify outliers and expected variance
  • Use identical hardware configurations when comparing test results when possible. When gathering results from other customers, be sure to note their hardware, software and network configurations
  • Maintain a history of previous build performance results to compare against current results. This will help developers identify whether an “outlier” run could be a legitimate performance regression if the values are well out of the scenario’s previous range

Produce actionable bug reports after measurements

  • When possible, provide performance logs, profiler data, machine configuration and other relevant data when reporting a performance issue. Replace vague adjectives in descriptions with concrete data (e.g. “300ms to open a new tab” rather than “slow on new tabs”)

Here are Messenger Companion’s current performance details:

Scenario

Elapsed time when Messenger Companion is signed-out (in milliseconds)

Elapsed time when Messenger Companion is signed-in (in milliseconds)

Cold Boot Startup Time

27

66

Open a New Tab (Tab Create)

20

62

Closing a Tab (Tab Close)

12

66

Closing the last Instance of Internet Explorer (Shutdown)

24

106

Being conscious of where your add-on completes expensive operations and investing in a performance measurement infrastructure can greatly decrease your add-on’s performance impact on Internet Explorer and improve users’ browsing experiences.  We hope that the information we’ve shared above will help you improve your add-on’s performance.  Do you have additional suggestions of ways to optimize add-on performance?  We’d love to hear them in the comments section below.

Windows Live Messenger Companion Team
Amanda Font, Program Manager
Hansel Ip, Software Engineer in Test
Wissam Kazan, Program Manager