An experiment to see if anything I do with popular JavaScript frameworks can match the performance of the search on the very large Handmade Hero episode guide. View the source code for details on each algorithm.

All of these execute the same search in the same amount of time. The differences you see here are purely from render times and DOM update times.

WARNING! Some of these are extremely heavy and may lock up your tab or your browser.

Vanilla (Naive)

This algorithm manually creates and inserts DOM nodes. This demonstrates the baseline performance for the "naive" method where all results are rendered at once.

This method is generally fast enough that the bottleneck is the browser calculating layout after DOM operations are finished. It is still slow enough, though, to demonstrate the need for a smarter approach.

Vanilla (Incremental)

This algorithm incrementally renders items by adding a few search results to the DOM each frame. This is the approach used on the actual Handmade Hero episode guide, and it results in a consistently responsive UI.

React (Naive)

This renders all search results at once using React. It incurs framework overhead on top of the usual DOM work, increasing mount times and adding a diff cost when many search results are already rendered.

React (Naive, Concurrent Mode)

This is the same as the previous, but rendering using React's experimental concurrent mode. No significant difference is visible; apparently the update work is still synchronous enough to block user input.

React (Incremental)

This renders results incrementally using React, gradually increasing the size of the result set. React does ok, but the increasing framework overhead (including diffing) grows as more items render.

React (Incremental, Concurrent Mode)

This is the same as the previous but with concurrent mode. This time the user experience is noticeably better, with less hitching on user input. To my eye, the initial performance of this method is nearly as good as vanilla, but the diff cost results in hitching after a large result set has loaded.

Vue (Naive)

This renders all results at once using Vue. Vue was by far the worst performer in these tests - by my timing, Vue is generally about 2x slower than React and 3x slower than vanilla.

Vue (Incremental)

I'll say this: Vue doesn't get any faster here.

Svelte (Naive)

Despite Svelte's claims of speed, it was generally middle of the pack in terms of performance. Here I measured it to be about 1.5x slower than React.

However, the performance of Svelte here seems wildly variable, probably due to the fact that Svelte seems to allocate the most memory of all three frameworks.

Svelte (Incremental)

Svelte remained middle of the pack here as well.