F# HTML DSL benchmarks for deeply nested pages - Falco.Markup vs Giraffe.ViewEngine vs Feliz.ViewEngine
Date: 2024-02-12 | create | tech | fsharp | html | benchmarks | giraffe | falco | feliz |
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.
- Falco.Markup: 0.007 ms
- Giraffe.Viewengine: 0.008 ms
- Feliz.ViewEngine: 0.03 ms
- Falco.Markup: 0.063 ms
- Giraffe.ViewEngine: 0.062 ms
- Feliz.ViewEngine: 0.264 ms
- Falco.Markup: 0.908 ms
- Giraffe.ViewEngine: 0.943 ms
- Feliz.ViewEngine: 3.152 ms
- Falco.Markup: 1.765 ms
- Giraffe.ViewEngine: 1.987 ms
- Feliz.ViewEngine: 6.651 ms
- Falco.Markup: 4.72 ms
- Giraffe.ViewEngine: 4.716 ms
- Feliz.ViewEngine: 18.018 ms
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: