Maintaining Great Site Performance
While Using the Zendesk Chat Widget

If you or a client use Zendesk for customer support, you're probably familiar with their Web Widget; a small button that sits on your website that allows users to access help documentation, send a message, or even access a live chat. For such a complex feature, Zendesk has made it very easy to install on a website. Embedding the widget is just a few lines of javascript code, and you're up and running.

However, with every easy widget installation, we have to ask ourselves what the consequences of web performance are. These small snippets are the gateway through which large libraries of application code run on your site, and the Zendesk Web Widget is no exception. The code injected by the Web Widget runs for all visitors, on all page views, whether the feature is used or not. The performance impact of this extra work is substantial and impacts both page speed and consequently, search rankings.

The solution to mitigate performance issues caused by third party widgets and other embeddable features changes based on how those third party services are implemented; there's no one-size-fits-all solution for optimizing third party code. We recently had an eCommerce client that ran into this problem with Zendesk so we put together a quick solution for them. Below is an outline and some sample code that shows how it works.

Making Zendesk Chat Lazy-Load

The Zendesk Web Widget has one important feature that drove our strategy for optimizing it: before a user interacts with the widget, it appears as a small button at the bottom of the screen. Why not postpone loading the entire chat application until after a visitor clicks the chat button? We can render a button on our website ourselves - there's no need to load everything proactively just to show a single button that most users won't interact with.

The default Zendesk Web Widget code looks as follows:

This is a fairly standard javascript async embed. The script is loaded and executed as soon as possible but it doesn't block anything else. The payload of the script in turns loads over 1MB of assets and application code that executes immediately.

Our goal was to only load all of these resources after the chat button has been clicked. To do this, we had to consider the different states we'll want the widget to be in:

  • Initial Load - For new visitors, we need to draw a plain button that is backed only by minimal javascript that launches the full Zendesk application on click
  • Subsequent Page Loads - One feature of Zendesk chat is that it will follow a visitor around as they click through the site. We need to make sure that subsequent page loads will load the full widget instead of our 'fake' button.
  • Post Click - After it has been clicked, we need to load the full application AND make sure it behaves as if the original button had been clicked. This ensures that a visitor doesn't have to click our 'fake' button and the 'real' Zendesk button

Each of of these required a bit of thought in order to implement. The first two were relatively easy. The fake button could be created with plain html/css and it is easy to execute the Zendesk-provided embed code in response to a click. We also recorded the click to local storage so that on subsequent views would load the full widget.

But figuring out how to open the Zendesk Web Widget after it loaded, artificially, was a bit tricky. After browsing the Zendesk documentation extensively, we came to the conclusion that there was no direct way to do this. There ended up being an effective workaround by taking the following steps after a click:

  1. Run the standard zendesk embed code
  2. Set an interval to poll for the existance of a zE object and zE.activate method which get created
  3. After these are created, wait a second for all of the code to execute, then finally call zE.activate() which will launch the Zendesk

So to put this all together, we put together the following code:

This is available here as a gist.

The code has three main parts:

loadZendeskChat(callback)
This will load the standard zendesk code, then do the polling necessary to establish when it has (mostly) loaded and run the callback.

loadAndOpenZendeskChat()
This will do just what it says! It will take our basic html button, add some 'Loading...' text to it while launching the real Zendesk Chat functionality and then deleting the 'fake button'

conditional if statement
This checks localStorage to see if the button has ever been clicked. If not, it places our fake button onto the page with an onClick handler to launch the real Zendesk chat. If it has been clicked before, it loads the Zendesk Chat code normally.

After your fake Zendesk Web Widget button is set up, you will be saving resources and providing a significant performance boost for all of your users, and you'll still be providing the same Zendesk support experience for those who need it. 

Leave the first comment