Skip to Content Collective Idea Home

Quick Win: Zendesk

by Daniel Morrison

I was given a chunk of code from a client today to add a tab on a site for Zendesk. You know, those tabs you see everywhere like GetSatisfaction.

Now, I don’t know anything about Zendesk, but I know a JS snippet when I see it. And I also know I can make it better. Here’s my quick win of the day:

First, the original code sample:

@import url(//asset0.zendesk.com/external/zenbox/zenbox-2.0.css);

<script src="//asset0.zendesk.com/external/zenbox/zenbox-2.0.js"></script>
<script>
  if (typeof(Zenbox) !== "undefined") {
    Zenbox.init({
      dropboxID:   "123456",
      url:         "fake-user.zendesk.com",
      tabID:       "help",
      tabColor:    "black",
      tabPosition: "Right"
    });
  }
</script>

Ok, not bad. I like that its fairly clean, and that they’re using protocol-relative paths. However, I know from Steve Souders that IE double-downloads stylesheets when they’re protocol-relative. So the first thing I do is specify https (for my use) or use Ruby to switch on the fly. Then, I moved that CSS to the <head> and dropped the @import part. Just made it: <link rel="stylesheet" href="//asset0.zendesk.com/external/zenbox/zenbox-2.0.css" />

Now onto the Javascript. I really hate seeing inline code in my html, so I moved it to a new file that I include with my other scripts at the bottom of the <body> (for high-performance reasons).

The first <script> tag will block the rest of the page load. Not very cool. Especially since this is just a support link, so I don’t need to wait for it to load. Time to make it asynchronous.

I have jQuery loaded already, so I use $.getScript() to make it non-blocking. Then I move the final <script> block to be a callback on the load. That way, it won’t fire until the file loads:

$.getScript('//asset0.zendesk.com/external/zenbox/zenbox-2.0.js', function() {
  if (typeof(Zenbox) !== "undefined") {
    Zenbox.init({
      dropboxID:   "123456",
      url:         "fake-user",
      tabID:       "help",
      tabColor:    "black",
      tabPosition: "Right"
    });
  }
});

Much better.

I don’t blame Zendesk for their original code. Its pretty good actually. However, that doesn’t mean we shouldn’t improve it when we can. Look for the quick win.

Comments

Brian Ryckbost
::

Any idea where they were using @import for the stylesheet?


Daniel Morrison
::

I can’t think of any good reason. From what I remember, @import makes it a non-parallel download.


Daniel Morrison
::

Did some reading to refresh my memory. @import won’t get seen by old browsers (Netscape 4, IE 5) so you can hide stuff from them. For most uses, that isn’t necessary.


James A. Rosen
::

I can tell you exactly why we were using @import for that stylesheet, since I wrote that template ;)

The problem is that IE7 wouldn’t apply the styles when they they were included in a tag. I had tried the version but found it rendered quite poorly on many customers’ sites. Changing to an @import worked fine. I’d love to see some reasoning on why this would be true.

As for the asynchronous Javascript import… if you already have jQuery, then I think your solution is good. I’m certainly interested in WebKit’s support of the “defer” attribute on Javascript tags. I think that is definitely worth pursuing for the broader audience.


Daniel Morrison
::

Thanks for the info, James!

I like your code snippet for being simple and concise. Much easier than telling people to install jQuery just for this. defer will definitely be cool eventually.


Emanuele
::

great man. you made my day!