Essay - Published: 2024.02.12 | benchmarks | create | falco | feliz | fsharp | giraffe | html | tech |
DISCLOSURE: If you buy through affiliate links, I may earn a small commission. (disclosures)
Last week we benchmarked F# HTML DSLs for rendering long HTML pages. This is useful if you're building pages with very large lists or tables. But this is a relatively rare occurrence IRL as you'll usually split up large pages with pagination or dynamic node rendering based on visibility.
A more common paradigm is to render deeply nested pages. If we think of a sufficiently mature / complex web page, it typically consists of several components - each of which is an Interactive Island. What this means is that we often have several sections of dense and deeply nested HTML trees on our page with none-few sections longer than 100 elements.
Previous deeply nested page benchmark revealed severe perf issues with raw string HTML rendering for deeply nested pages when compared to HTML DSLs (a difference of 1700x at scale). So in this post we'll be comparing how different HTML DSLs stack up for this workload.

In this benchmark, we build a simple HTML page containing a series of n nested divs from size 10 to 5000. Each div contains text containing its index and the next nested div.
Benchmarks are run and aggregated with BenchmarkDotnet on a free Replit instance.
You can access the code and run the benchmark yourself on Replit - F# HTML DSL - deeply nested page benchmarks Replit

Falco.Markup and Giraffe.ViewEngine show very similar performance profiles throughout the workloads. Falco.Markup generally wins by a small fraction (< 10%) with the absolute difference coming out to tenths of a millisecond.
Both outperform Feliz.ViewEngine by about 3x with absolute differences in the 1-10 milliseconds range.

In this section I'll share the raw results for posterity.
10 items

100 items

1000 items

2000 items

5000 items

Overall Giraffe.ViewEngine and Falco.Markup perform very well and are pretty easy to work with so would recommend those for your HTML DSL rendering needs. Feliz.ViewEngine is still pretty fast but coupling its relative slowness with its kinda clunky API and lack of recent updates makes it seem a less attractive choice from my perspective.
If you have suggestions for other HTML DSLs you'd like benchmarked, send them my way! Every time I publish one of these I discover new ones people are using.
If you liked this post, you might also like:
The best way to support my work is to like / comment / share for the algorithm and subscribe for future updates.