Publish/Subscribe with jQuery Custom Events

The Publish Subscribe or pub/sub pattern is used to logically decouple object(s) that generate an event, and object(s) that act on it. It is a useful pattern for object oriented development in general and especially useful when developing asynchronous Javascript applications. This post explores its implementation in jQuery.

The Dojo javascript framework provides an explicit topic-based mechanism for “publishing” and “subscribing” to events. Peter Higgins, Dojo’s author, has also written a jQuery plugin that replicates this functionality. It weighs in at under 30 lines of code… but why use 30 lines when you can do it in zero?

jQuery custom events provide a built in means to use the publish subscribe pattern in a way that is functionally equivalent, and syntactically very similar, to Higgin’s pub/sub plugin: Just bind observers to document.

In the above code, you could have used any object, not just document. But by using the document object, you give yourself the ability to leverage the full power of jQuery events. Triggering events on the objects that actually generate them gives you event bubbling, sets this, etc – and a simple Dojo-style “subscriber” that is bound to the document doesn’t even have to know:

This works great for DOM elements, but what if the event that you want to publish isn’t associated with one? It’s not widely used, but the jQuery object can be passed regular javascript objects. And to bubble events, jQuery relies on two properties: parent and ownerDocument. So the pattern can be extended to any object:

So why would you use a separate publish/subscribe system rather than just relying on jQuery events? One word: performance. I used my “better jQuery pubsub” pattern with a trivial event handler, and implemented the same thing with Higgins’ plugin. I then ran 10000 events through each system:

10000 Events

Firefox

Chrome

jQuery Events

753ms

201ms

Pub/Sub Plugin

89ms

9ms

I repeated this a few times with consistent results. Clearly, jQuery/DOM event performance is an order of magnitude worse than a special-purpose system. At .08ms of overhead per event, though, I don’t think this will be an issue for most uses. Still, if you are running over 100 events per second and/or bubbling your events up a long tree, the jQuery/DOM event system overhead could hurt performance and in any case it is always worth testing. Otherwise the benefits of having a unified event semantics and fewer dependencies, and the power available to you with bubbling etc, make jQuery events the clear choice.