What performance can I expect from Halogen relative to Elm?

This is more of a chat than a request for help, though I am hoping to pick up some knowledge from other people’s posts, as I do from the other topics here.

My use case is to display rapidly changing financial quotes in table like component(s)

I wanted to see if functional language frontends can do a good job of this. So far I am impressed by Elm.
On my 2020 iMac, it handles updating of > 200 fields up to around 6000 times/sec , ie. over 1 million numbers updating every second. If a server sends more data than that (I randomly generate new values as often as I want), I start to see a lag - when I kill the server, the frontend continues to update for some more time

Now I am trying to learn purescript and Halogen so I can implement the same thing. I really want to program in purescript, and I am really hoping the performance will be good enough. The good news is that even a third of what I observed with Elm should be good enough.

BTW, Elm was trivial to learn. I googled for examples and skimmed tutorials, and was able to get this simple websocket client working in a day or two. The only relevant knowledge I had was React and some fooling around with Haskell over the years ( I still struggle with monads).

My small poc functional app (with an Elm client for now, hopefully Purescript client to come) is here. This tests the main performance demanding use case from a React/Redux app on which I worked a few years ago.
I apologize that its setup is a bit elaborate and fiddly. Nor is a running version available on a public website. I am only including the link in case someone wants to look in the elm-client/src to see what I am doing (a small amount of Javascript ‘port’ code to set up the websocket client, and a couple of hundred lines of Elm)



FWIW, a long time ago I tried setting up a PureScript project that would use React & Plotly and throw up 2 line charts of 500 points of randomly generated data, and refresh them with new random data as quickly as possible and track the refresh rate. When I run it on my Lenovo Yoga 2 that’s a couple years old, it gives me a refresh rate of around 20 Hz.
Source code here. I make no promises for code quality, as I wrote it quite some time ago :wink:. If you felt like trying it out, you would just spago install, npm install, npm start.

(sorry that looks wrong because my gif capturing tool isn’t recording 20+ Hz, so it looks like it’s only refreshing about 5Hz, but that’s not because of PureScript)


Thanks, I will check this out. I am interested Plotting realtime data , and I am a little familiar with Plotly and obviously React. So I should be able to get something out of your project without too much effort.
That looks pretty fast, and plenty fast enough for whatever I would want to do.

PS: How do you get Refresh rate to show in your GIF? Does Plotly support that?

1 Like

No I’m manually tracking it with program logic. I grab the time at each render, and do the diffs in PureScript code.
Here I grab the current time in an effect hook that runs on every render, and here I calculate and update the average refresh rate over the last 10 renderings. I think that’s accurate unless there’s some weird optimization such that React is calling render more often than Plotly is updating the chart. It also looks about 20 Hz to me if I just eyeball it, so I just went with it because it seemed right :laughing:


Cool, Very nice trick that I can use

1 Like

Halogen is not going to be faster than elm-html in raw benchmarks. Elm-html is a 100% (hand-tuned) JS library. I wrote halogen-vdom which powers Halogen, which has the goal of being written in PS as much as feasible, while still retaining production-level performance. In the past, testing raw halogen-vdom, it’s easy to get at least 60 FPS with some thunking (using the old DBMon benchmark). Halogen itself is written in a more “idiomatic” FP style (just that it’s not trying to eek out performance by using EffectFns everywhere). Halogen also does not pervasively synchronize with requestAnimationFrame.

If you want to try a minimal Elm-like in PureScript, you can also try spork, which I maintain, but do not actively develop. It’s meant to be something people can use to try out PS quickly if they’ve had experience with Elm before.


Thanks Nate. I do want to use idiomatic functional code as far as possible, and Halogen seems the best option out there.
If Halogen is 5x slower for my use case above, and 10x slower than Elm in the worst possible performance benchmark for Halogen, I could probably live with that.

1 Like

I don’t have any real numbers, but I think it’s likely that elm-html is in the range of being twice as fast as Halogen. The is going to depend on heavily on your use case though, and there are potentially cases where Halogen could be comparable depending on the architecture. Halogen updates at the nearest component boundary (much like React), so it’s possible to exploit that. If you are only using Halogen in a TEA style (single global component), while this is possible, you aren’t getting much from Halogen in that case.


Great, Thanks. Sounds like Halogen is going to be fine for me.

I have been reading the Halogen performance threads here, and totally get the Render optimization issues you guys talk about.
(I developed a medium size React (v15) App with only functional components wrapped by utilities in recompose library, hand tuned the props diffing to get good enough performance out of React)
I am convinced by those other threads that I should be using multiple Halogen components mixed with some memoized html rendering functions.

I checked out Spork, looked over the examples, built and ran them It is a ‘delightful’ library!
I think I had found Spork before, but being a beginner, was scared off by the fact that it doesn’t use the current version of Purescript and doesn’t use spago. At this point, I am only thinking Halogen. I would use Spork alongside Halogen if it were more performant and it is not too hard to mix the two, at least at the top level within the same app.

1 Like

AFAIK, spork is in the latest package set, so there isn’t any issue with using it with the existing compiler or with spago.


I didn’t understand the difference between how the package itself is built vs how it is used
Thanks for explaining

1 Like