Comparing F# HTML DSLs for Rendering long web pages - Falco.Markup vs Giraffe.ViewEngine vs Feliz.ViewEngine
Date: 2024-02-02 | create | tech | fsharp | benchmarks | giraffe | falco | feliz | html |
Last year I started building fullstack web apps with F#. I found the devx of using a single fullstack monoolith to be far superior to multi-monolith, even when that meant losing access to popular SPAs like React, Svelte, and Vue. Building apps with F#, HTMX, and HTML rendered via DSL has been a breath of fresh air for web dev that I didn't know I needed.
There are several popular HTML DSLs to choose from in F#. I've previously focused on using Giraffe.ViewEngine as it performed well in my previous benchmarks and pairs well with F# / Giraffe, the web framework I've used in CloudSeed (my F# project boilerplate) for several years.
But several Fsharpies requested additional benchmarks comparing other HTML DSLs so here we'll be comparing Giraffe.ViewEngine, Falco.Markup, and Feliz.ViewEngine to see how they stack up.
Benchmark Setup
The benchmark builds long, shallow pages.
For this benchmark we build simple HTML pages containing a long list of items in a table, ranging from size 10 to 5000.
We benchmark using BenchmarkDotnet on a free Replit instance.
You can access the code and run the benchmark yourself on Replit: F# HTML DSLs - Long, shallow page benchmark Replit
Results Overview
In general Falco.Markup > Giraffe.ViewEngine > Feliz.ViewEngine. Falco.Markup comes out to ab 5-10% faster than Giraffe.ViewEngine and both are ~5x faster than Feliz.ViewEngine.
The absolute difference in these is on the order of 1-5 ms for pages up to 1000 items and 10s of ms up to 5000 items, so pretty fast all things considered.
Detailed Results
In this section I'll paste my results from BenchmarkDotnet for posterity.
10 Items
- Falco.Markup: 0.015 ms
- Giraffe.ViewEngine: 0.016 ms
- Feliz.ViewEngine: 0.053 ms
100 Items
- Falco.Markup: 0.105 ms
- Giraffe.ViewEngine: 0.101 ms
- Feliz.ViewEngine: 0.500 ms
1000 Items
- Falco.Markup: 1.354 ms
- Giraffe.ViewEngine: 1.393 ms
- Feliz.ViewEngine: 5.957 ms
2000 Items
- Falco.Markup: 2.553 ms
- Giraffe.ViewEngine: 2.921 ms
- Feliz.ViewEngine: 12.015 ms
5000 Items
- Falco.Markup: 6.294 ms
- Giraffe.ViewEngine: 7.350 ms
- Feliz.ViewEngine: 32.632 ms
Next
Overall these are all pretty fast. Obvs you need to benchmark with your own code on your own machines to see how it will really perform in production but they all seem to perform reasonably well.
Personally I'd probably opt for Giraffe.ViewEngine or Falco.Markup as they seem to perform best and have a cleaner API in my opinion. That said, all of these DSLs can render to string so it's easy to mix and match with whatever framework you want to use.
If you liked this post, you might also like:
Want more like this?
The best / easiest way to support my work is by subscribing for future updates and sharing with your network.