Over the last few years, there’s been a big movement on making Mozilla code really, really fast. Which is wonderful. A fair bit of this has been in “quick stubs” – specifically, optimizing how JavaScript (aka JS) code calls into C++ code. For instance, the HTML input element has a quick stub for the value property, bypassing much of the XPConnect gobbledygook.
This post is about the reverse: frequent calls from C++ code to JS code. Calls like that don’t have the direct path. They go through XPConnect. This is understandable – JS code can do pretty much anything under the sun. Plus, there aren’t many areas where C++ calls on JS. The most notable spot is DOM event listeners, but again, they can do anything.
On the other hand, there are specific interfaces where the JS author is supposed to do only very simple things – or where the first few actions taken are validation (“does this event have a keyCode I care about?”). The NodeFilter interface from DOM Traversal comes to mind. It’s supposed to check a node’s properties and return a simple value. A NodeFilter you pass into a TreeWalker or NodeIterator will be called for any node of the specified node types.
This is the kind of thing I look at and think, “Why don’t we get XPConnect out of the way, by having native code do the repetitive work?” JavaScript is a glue language, where you can connect components together. So we could use JavaScript to assemble a C++-based NodeFilter, which then gets passed into the native TreeWalker. The purpose of this “intermediate filter” is simply to call on the JS code less frequently.
Now, I admit, node filters aren’t the most compelling case for pre-assembly. (I have my reasons for wanting that, but they’re not common cases on the Web, I suspect.) An event listener, though, would be more compelling. I’d wager a native ProgressEvent listener, filtering on the readyState property before possibly executing a script-based callback, would be nice. So would a native keypress event listener, based on keystrokes to a form control.
There’s even a bit of precedent in the Mozilla Firefox code: the “browser status filter”. I admit this poorly-documented web progress listener has caused me pain in the past, as it filters quite a lot… but that’s the point: it hides a lot of unnecessary cruft from JavaScript code that frankly doesn’t care! I also think JavaScript typed arrays are a point of comparison.
I think a few intermediate filter classes like this could have a measurable impact (ok, maybe small) on frequent calls from C++ to JS. I don’t know if they would… but I think in the right places they could. The major downside I can see is to readability of the code.
Opinions welcome!