Deopts: The Line

I was implementing HTML tag identification into FastMin in order to properly handle special tags like style, script, and pre when I came to an important decision: how should I choose the appropriate action to take once I've identified the tag? If this doesn't sound like a complicated problem, that's because it isn't, really. In both JavaScript and PHP it is possible to created a simple object and map each tag's name as a property and its minification strategy as the corresponding value. But there was more to it in this case.

The code that I was writing (the JavaScript code, at least) was written with the intention of being as simple as possible to compile into native code. I wasn't using fancy features of JavaScript like dynamically allocated arrays, strings, and objects. In fact, I was avoiding them completely. But how taxing would accessing an object property by string be, really? Surely using a library to handle multiple string matching would cost more than one line of code, right?

Well for the sake of argument I wrote one anyway. Matcher takes a sorted array of strings at initialization and identifies the subset of compatible matches as you supply it with characters (or whole strings). Why a sorted array? So that the matching can be done in logarithmic time for each character using binary search. This makes for a worst case running time of n*log(n) (log(n) on average) It is written in the same manner as FastMin, with engine optimization on the mind. Because Matcher offers the array index of the matched string upon successful match, an array of strategies can be created to correspond with the match array. This eliminates the need to create a dictionary object.

It's an awful lot of code to avoid a one-line solution, so there should be a loss in performance, right? Using Matcher in FastMin actually led to a performance increase of 57%. I was astounded. As it turns out, a single unoptimizable line causes the entire enclosing function to be deoptimized. So, the simple act of accessing an object property by string triggered a deoptimization that hampered the entirety of HTMLFastMin.

As a result of this discovery, I've been working to ensure that both Matcher and FastMin are free of such offending code. The new version of FastMin hasn't been merged at the time of writing, but is on its way. If you want to profile your own JavaScript for deoptimizations, you can run node (or iojs) with the --trace-deopt flag.

io.js and Harmony

Lately I've been experimenting with Node.js and have been absolutely loving it. I've got a fully functional version of this blog running in Node at the moment. Recently, the future of Node has gone public, complete with the latest version of V8 and default support for the latest ES6 (Harmony) features it has to offer.

In the spirit of Harmony and io.js, I've updated FastMin to include a highly performant io.js variant complete with stream support.

Fast Minification

While hunting for an efficient CSS minifier, I happened across Jonathan Walsh's CSSFastMin, which minifies CSS with linear time and space complexity. This is done by processing each character in the input file in a switch statement which emulates a state machine.

Fascinated, I ported his solution to PHP and added a few additional enhancements in the way of minification. I also created rudamentary minifiers for HTML and JavaScript based on the same model and am currently testing them on this very website. The beauty of them is that they can be passed into ob_start() in order to minify code on the fly.

There are many more optimizations I'd like to make for improved minification, but I've made the scripts available on Github for the curious.

CUI

CUI is inspired by Palm (now HP) WebOS, which is a Linux-based operating system with a front end entirely developed in HTML5. I challenged myself to offer similar features in a mobile-focused web app in order to sharpen my skills with HTML5, JavaScript, CSS3, and PHP5. The only components of CUI that aren't fully written by me are the mp3 metadata libraries and the simple JavaScript class inheritance structure, which is based upon John Resig's example.

Part of the challenge of developing CUI is ensuring that the user experience is fast and responsive. CUI makes use of hardware acceleration to keep animations and swipes smooth and steady. Changes to the DOM are often deferred to the next available frame – using window.requestAnimationFrame() – in order to ensure that transitions are consitent. Using this method in event callbacks keeps the cost of executing the callback light so that the next can fire, as some events (such as touchmove) are fired rapidly.

CUI is also a combination of experiments in User Experience. Multitasking is possible in CUI without demanding screen space or even that it be used. It is discreetly hidden as a sidebar which can be opened by swiping into the screen from the left side. When loading CUI, it is shown briefly before gently sliding offscreen. Note that in order to access the multitasking sidebar in iOS, it is necessary to add CUI to your homescreen and launch it as a web app from there. Mobile Safari overrides swipes from the left side for its own purposes.

Animus

Animus is an attempt to recreate the Animus interface from the first Assassin's Creed game using SVG and canvas. I created a two-dimensional representation of the display in SVG and used canvg to draw it onto a canvas used as a cache. When the front-facing canvas is updated, vertical slices are drawn with varying height in order to created the three-dimensional effect. Drawing each slice comes with a performance cost, and so to improve performance the width of each vertical slice varies: there are fewer, thicker slices towards the center and more thin slices towards the end where more detail is necessary in order to accomplish the 3d illusion.