Wednesday, February 13th, 2008

Is easy implementation the same as good code?

Category: Accessibility, Examples, JavaScript, Security, Unobtrusive JS

I’ve just come across a solution for badges on web sites that makes it terribly easy for implementers. The idea is that the implementer could add a badge wherever they want in an HTML document, choose the look and feel and add a message to be shown. The implementation code is the following:

  1. <script src="badge.js" size="small" skin="blue">Brandname</script>

The badge script then replaces the script node with the badge using the settings defined for each script include. Clever, right? Well, almost. Security concerns and invalid HTML aside (the attributes – content inside a script is valid and should be ignored according to the W3C when a src attribute is present) there are many more issues with this:

  • you need to loop through all script nodes, read the info and create the correct badge – this can get slow
  • the badge.js script gets called over and over again, even if it is only needed once (granted, it will be cached)
  • every script inside a body makes the rendering engine stop, pull the src and try to execute either that or the content of the node – this makes for terrible performance.

I’ve written up an example of how the above works and three alternative solutions that work around these issues.

What do you think? Should the ease of implementation be the success factor or the performance for the end user?

Posted by Chris Heilmann at 7:45 am

3.2 rating from 26 votes


Comments feed TrackBack URI

One of my pet peeves is having to wait for 3rd party scripts to load when visiting a site. It’s also one of the least addressed issues on the web. The accepted dogma is, “just plug this into your site and forget”, except that in doing so, sites slow way down because of it. So reducing the number of times a 3rd party scripts are called is a big thing for me. Thanks for putting the effort into this article.

Comment by arapehl — February 13, 2008

The issues mentioned above don’t seem valid to me. Here’s why …

Issue #1, “looping through script nodes is slow”. Only true if there are 1000’s of nodes in the DOM. Even then, getElementsByTagName is probably very performant compared to the rendering time required for a DOM of that size. I don’t see this as something to be concerned about.

Issue #2, “badge.js is called over and over again”: Only true if the browser doesn’t cache the script. But if you set the HTTP caching headers properly this won’t be an issue. The script is small enough that fetching it _from the cache_ repeatedly should be fairly fast.

Issue #3, “script tags make the rendering engine stop and pull the src”: This is just a restatement of Issues #1 and #2. The engine stops while it fetches the source (see Issue #2) and executes the script (see issue #1).

The “real” problems are…

1. The use of non-standard HTML attributes for the script tag
2. The equally-questionable practice of placing non-script content inside a script block
3. Page rendering depends on 3rd party servers to be performing well

The alternative solutions address the first and second issues, but still require script hosted on external servers. (that said, including the script at the end of the page will moderate the effects of said servers not responding in a timely manner).

In many cases, the best solution to this sort of problem is to provide a “configurator” tool that provides a friendly interface for generating the desired HTML markup, which users then simply paste into their page.

– Explains all the options to users
– Allows them to experiment and preview
– Inline code renders immediately
– Inline code doesn’t require scripting DOM elements
– Inline code doesn’t depend on 3rd party servers

Comment by broofa — February 13, 2008

I agree with the last commenter: performance isn’t going to be a concern here, the issue is correctness. Something like this is just simple, just as easy to understand, and a lot more correct. And under the hood, there’s no good reason why Badge.create() couldn’t do its work on the cheap, by doing document.write()’s or whatever.

<script src=”badge.js”></script>
<script>Badge.create(‘small’, ‘blue’, ‘ABC’);</script>
<script>Badge.create(‘big’, ‘red’, ‘XYZ’);</script>

Is this harder to understand?

Comment by sentientholon — February 13, 2008

Am I alone in wondering what the heck a badge is, and why it would need to be loaded from a third party?

Comment by Jon Hartmann — February 13, 2008

@Jon: A badge, as in, the little widget you can get from Flickr to put your pictures on your own site.

@broofa & @sentientholon: Third party script implementations are inherently slow because you need to poll yet another server for content and are completely at the mercy of its present lag conditions. Not only that, but odds are that a site using third party scripts isn’t using just one (analytics script, a couple of badges, etc…) so your level of uncertainty and lag time just multiply in those situations. Worse still, if you drop a script tag in the middle of your page or at the top, and you happen to be trying to access the page during a particularly high traffic period for that service (say Flickr, or Google Analtytics), then you *will* have to wait for that server to respond before your page finishes rendering. And that is very noticeable. Lastly, using non-standard attributes is just bad karma. I’ve found repeatedly in the past that if you break away from the standard, you’re opening yourself up to a wide breadth of unintended consequences. Basically the unknown. You know, somewhere down the line, some conditions arise and you end up with an “oops, didn’t think of that” situation.

Just sayin’…

Comment by arapehl — February 13, 2008

@arapehl: I think we’re basically in agreement. The only distinction I’d make here is the difference between importing one 3rd party script multiple times (the case referred to in the original article) .vs. calling many different 3rd party scripts, which you’re alluding to. The former case is a non-issue due to caching, as I said. The latter case, as you point out, can be problematic. However as long as the 3rd party servers have as good/better performance then site hosting the page than it’s not that big a deal. Which is why google ads, analytics, flickr – the high profile sites you mention, in fact – are able to do this _without_ it being a problem. They put a lot of time and energy into making sure those services are robust and *fast* because if they don’t serve those scripts reliably, they lose customers and $$$. But will prove as reliable? ‘Depends on who they’re hosting with I expect.

Comment by broofa — February 13, 2008

“Security concerns and invalid HTML aside (the attributes – content inside a script is valid and should be ignored according to the W3C when a src attribute is present)”

HTML == SGML and is not strict about undeclared insertions of attributes.

XHTML == strict XML and invalidates undeclared insertions of attributes.

Don’t confuse the two. HTML 4.01 is still good stuff; XHTML is overrated.

Comment by stimpy77 — February 13, 2008

do you need to loop all script-tags? isn’t the last script tag the current?

Comment by Lon42 — February 13, 2008


Comment by ilazarte — February 14, 2008

Hm… the above didn’t work, let’s try again.


Why not make it a query string? Seems like this particular example was reinventing the wheel.

Comment by ilazarte — February 14, 2008

ok, the code tag does nothing, i give up :) happy valentines day!

Comment by ilazarte — February 14, 2008

Depends on what you make money off of. If more badges displayed on more pages = more money for you, ease of badge embedding wins.

Although, I think you can make a nice badge-maker or something that’ll churn out decent embed code. That’ll probably make it even easier to embed than editing html attribs.

Comment by Kingsley2 — February 18, 2008

Leave a comment

You must be logged in to post a comment.