The TodoMVC variants compared
The nine pages before this one walk through one variant each. This page sets them side by side. Every number here is measured on the repository amber/amber-todomvc as the pages quote it, with Amber 0.32.0. TodoMVC, one app per library says what the variants share.
The numbers
The view is the variant’s package without its tests. Its lines are the non-blank lines of the .st file, class comments included, and chunk marks left out. The bundle is what grunt deploy writes for the page, with Amber, the model, the view and its libraries, before minifying:
| Variant | Classes | Lines | Bundle | In the bundle beside Amber and the model |
|---|---|---|---|---|
| The DOM alone | 2 | 151 | 434 KB | nothing |
| jQuery | 2 | 132 | 512 KB | Wrappers-JQuery, jQuery |
| Web | 2 | 129 | 471 KB | Web |
| Web with jQuery | 2 | 131 | 555 KB | Web, Web-JQuery, Wrappers-JQuery, jQuery |
| Web with snippets | 1 | 115 | 499 KB | Web, Web-Snippets, DOMite-Snippets, Domite |
| Silk | 2 | 129 | 454 KB | Silk, Domite |
| Silk with snippets | 1 | 113 | 464 KB | Silk, Silk-Snippets, DOMite-Snippets, Domite |
| Silk with MiniMVP | 6 | 206 | 468 KB | Silk, Domite, MiniMVP |
| Mithril | 1 | 126 | 459 KB | Mithril |
The DOM alone is the smallest bundle and the longest view. jQuery adds 78 KB to it. Silk and Domite together add 20 KB, and Web 37 KB. The three variants with one class have no object for a todo. The two with snippets copy markup, and Mithril answers nodes. MiniMVP has a class per part of the page.
The four axes
| Variant | How the DOM is built | Where the markup lives | How events bind | How the view follows the model |
|---|---|---|---|---|
| The DOM alone | createElement:, element by element |
in the code | addEventListener:do: |
renders everything again |
| jQuery | asJQuery on a string of markup |
in the code, as a string | on:do: |
renders everything again |
| Web | tag messages on a canvas | in the code | onClick: and the others, on a brush |
renders everything again |
| Web with jQuery | tag messages on a canvas | in the code | on:do: on the page, onClick: in the item |
renders everything again |
| Web with snippets | copies of a snippet | in the page | onClick: on brushes made from elements |
renders everything again |
| Silk | tag messages, LI: and the others |
in the code | on:bind: |
renders everything again |
| Silk with snippets | copies of a snippet | in the page | on:bind: |
renders everything again |
| Silk with MiniMVP | tag messages, one presenter per part | in the code | on:bind: in a presenter |
refreshes each part from its data |
| Mithril | virtual nodes, m value:value:value: |
in the code | an attribute of a node | redraws, and Mithril changes what differs |
Seven variants render everything again after every change, and the list is small enough for that. The two others follow the model more finely. MiniMVP refreshes a part when its data changed, and Mithril compares the new nodes with the old ones.
What each has no word for
Each page ends with what its library leaves to the DOM. Side by side:
- The DOM alone has a word for everything, and none of them is short. Building an item takes 32 lines.
- jQuery has a word for everything too. The markup of an item is a string in the code, and every event, class and property is a string.
- Web has words for building and none for elements that are already there. Finding one inside another, reading or setting a property, and one class among others reach the DOM. So do a handler taken back and an event of the window.
- Web with jQuery gives each of those a jQuery word. The cost is two APIs on one element, with
asJQuerybetween them. - Web with snippets gets a brush on the caret back from a snippet and nothing on the frame. The item is reached from its label with
closest:. - Silk reaches the DOM three times:
focuson an element, andlocalStorageandlocation hashon the window. - Silk with snippets reaches it the same three times.
frameanswers the item from the caret. - Silk with MiniMVP has no parent presenter with given children, and none over a collection whose members come and go. The children of a hidden part stay as they were. The variant writes the first two and lives with the third.
- Mithril has everything a view needs, and the cost is at the boundary.
nilis notnull, a function with properties is opted out, and the view redraws at once for the tests.
Reading the tables
The variants do the same work, and the tests say so. What differs is where the work goes. The DOM alone spends it on building. jQuery and the Web variant with it spend it on a second vocabulary of strings. Web spends it reaching past the brush. Silk spends the least on either. The two snippet variants move the markup of a todo into the page. They pay by setting its state after the copy is in. MiniMVP pays in classes and gets a partial refresh. Mithril pays at the boundary and gets the diff. The pages of this site build the page with Silk and with Web. The JavaScript page is enough for every reach past them.