It’s out.
It transformed.
And it’s more than meets the eye.
(Download links at the end of post ↓)
For one increment in minor version, jOrder went through significant changes. In fact, more work hours, checkins, and lines of code went into getting from 1.1.0.14 to 1.2 than all that leading up to 1.1.0.14.
I set these four goals for version 1.2:
- complete refactoring / restructuring
- near-100% unit test coverage
- implementing consistent data modification
- maintaining performance figures
Restructuring
Two words: spaghetti code. Thousand-something lines in one JS file is just not bearable. Before 1.2, jOrder lacked any structure beyond the table and index objects. There still lay a good amount of code that could be lumped together, for the sake of extensibility, into smaller, self-containing units.
The technical challenge here was keeping 1.2 backward compatible. It seems that the right mixture of inheritance and method delegation cracked the problem.
For instance, index was broken down into four objects: index, signature, lookup, and order. The latter two inherit from signature, while both delegate methods to index, the object that keeps all index operations together, and from the outside, looks about the same as before.
The class diagram illustrates the new structure. It’s not a thorough class diagram, for it shows only the public properties and methods. It does indicate however the connections between components. A more detailed post on jOrder’s inner workings will follow sometime soon.
With this change, jOrder achieved the following:
- what previously was about 1000 lines in one file, is now 1500 (heavily commented) lines in 12 files neither of them being bigger than 400 lines
- what belongs together (and only that) is actually in the same file now
Test coverage
Over 130 unit tests (and growing) make sure the library works exactly as it should, and that backward compatibility issues did not and will not arise. Indeed, thanks to these tests, right after refactoring, jOrder worked in live applications with minimal adjustments.
The tests are built upon QUnit.
Check them out in the jOrder GitHub repo.
Consistent modification
Modifying data was already working in pre-1.2 versions, but you had to rebuild the indexes manually after each insert, update or delete. For ordered indexes, this meant another Array.sort() on the whole table for each affected column.
Since browsers implement different sorting algorithms for Array.sort(), it is quite unpredictable how many steps between O(1) and O(n*log(n)) re-ordering will take depending on the current table order.
As updating wasn’t much of an issue in my own jOrder-based applications until now, this method – inefficient as it was – sufficed. But as you draw closer to the limits of jOrder in reducing traffic by getting rid of unnecessary ajax calls – you start to look elsewhere, ie. reducing the size of ajax calls that remain. That’s only possible when you keep client and server data in sync. Which, when dealing with tens of thousands of rows, makes frequently calling Array.sort() not to be an option.
Instead, each time there’s an insertion or update, we look up the position of the new entry within each index, and splice it in. As benchmarks show, building an index this way this is not much slower (about 10-20% on average) than running Array.sort() once, and you have a consistent index after each insert.
You can still opt for leaving indexes untouched after changes, but then you’ll have to take care of rebuilding the indexes manually.
Performance figures
Severe changes to a project’s codebase always risks performance issues. As the primary goal of jOrder is to be fast, I needed to make sure the benchmarks still put it in the same ballpark as before. So I took all JavaScript data manipulation projects I could find, and compiled a rather comprehensive performance comparison. I even wrote a benchmark framework (jOrder Benchmarks or jOB) for that purpose.
Luckily, according to the benchmarks, I didn’t mess up jOrder’s existing advantage in speed. The figure below is taken from the linked benchmark page and shows how jOrder performs against other libraries in initializing, searching and sorting a table of 1000 rows.
One of the next couple of posts will expand on benchmarking and general browser performance issues that have an impact on jOrder’s speed. Until then, feel free to check out the benchmark source (benchmarks.js).
Get it
Download (or hotlink to) these files:
- Minified: https://github.com/downloads/danstocker/jorder/jorder-1.2.min.js
- Human readable: https://github.com/downloads/danstocker/jorder/jorder-1.2.js
- Full repo ZIP: https://github.com/danstocker/jorder/zipball/1.2
- Full repo TAR.GZ: https://github.com/danstocker/jorder/tarball/1.2

When I first heard about jQuery, the “query” part in the name led me to think it had something to do with data querying. And, it’s in JavaScript, too, so it must be some sort of lightweight client-side data management library. It was a disappointment to learn that it’s not, but I’ve gotten to like and use jQuery since, nevertheless.