Elm-ui, tables and performance issues

Hi there :wave:, recently I’ve been working on a small personal accounting application in Elm. Basically importing bank statements from CSVs, categorizing them and showing monthly overviews of income and spending by category. It’s not yet ready to be shared, but I intend to open source it once it has some kind of MVP-ish completeness.

I’m using elm-spa and elm-ui.

Naturally, I have pages with “large” tables, especially on the basic “Book” view that shows the entirety of all bank statements in the DB and has some filtering and sorting options.

But this page gets super slow with my test data of only ~1700 rows (in practice it’s going to be more than that, I’d expect in the order of 5-10K statements). Using the helpful guidance from Performance Optimization, I was able to pin down the performance bottleneck: combining stylesheets of elm-ui elements is what takes about 40% of the time: $mdgriffith$elm_ui$Internal$Model$toStyleSheetString</combine<, which calls _Utils_ap, the elm-core implementation of append.

If I replace the elm-ui table with a Html.table element, the app is super snappy, which confirms the source of the issue. But obviously I’m loosing all the the nice styling options of elm-ui (if it were only colors and spacing I guess that would be okay, but there’s also inline editing / input fields and other, harder to replace ui elements).

I did use Element.lazy and it did provide a little bit of speedup, but by far not as significant as with the Html table.

So my questions are

  1. Does anyone have prior experience with large tables and elm-ui performance and some optimization ideas?
  2. How I place the Element.lazy calls strategically? I put it just in front of the Element.indexedTable call to get some speedup. But when I use it for every single table cell, it actually slowed the whole thing down (to a point worse than without Element.lazy at all). It would be great to have this per-row, because that’s the level on which the ordering and filtering logic is being applied, but I don’t see how I could achieve that with Element.table or Element.indexedTable.
  3. I noticed that elm-ui does not produce elements, but aligns each cell individually, which of course leads to per-cell unique styles. Is there a way to make elm-ui able to understand that there are basically only a handful of styles to be applied (up to positioning)?
  4. I’d like to see/try whether GitHub - mdgriffith/elm-optimize-level-2 can help, however because I’m compiling with elm-spa, it’s not clear to me how I could pass on other compiler flags - pointers would be greatly appreciated.
1 Like

Hello!

Sorry this it probably a bit frustrating :pray:

Elm UI 1.x wasn’t really designed for large interactive tables (though this should be fine in elm-ui 2.0)

Yeah, Elm Optimize Level 2, may give you some speedups for free. Unfortunately I’m not familiar with what’s possible with elm-spa, so not sure how to make those two tools play nicely with each other.

You also might try paginating your table and only rendering a smaller number of rows at a given time.

The problem with Element.lazy is that it embeds an inner stylesheet, which causes long style/layout steps when rendering. Which means it can have the unfortunate side effect of making things slower the more you use it :frowning:

One of the focuses of elm-ui 2.0 has been performance, so there are some significant speedups coming(including no issue with lazy, and much faster baseline rendering), but I can’t guarantee exactly when it’ll be out. I’m shooting for a month or a month and a half from now. If you’re interested, I’ll be looking for people to try out an alpha version sooner than that (I’m currently using it for an app I’m building).

7 Likes

Thank you very much for the swift reply!

Actually the experience is way less frustrating than wrangling with CSS, so far it’s been a good trade :smiley:

Pagination is a good idea I had not though of. Implementing that is definitely the better option compared to using plain html for the table. So at least there is an escape hatch.

I’d be very glad to test elm-ui 2.0 in an alpha version. I’m currently quite actively working on said app and as it happens I’ll be having more time than usual in the next month.

1 Like

OK wonderful! I’ve put you on a list I’m keeping internally and will ping when things are good to play with.

1 Like

Pagination/infinite scroll is the way to go.
Elm-ui table run fine here with 200k rows as long as you paginate.

data = 
  myRows
    |> List.drop (pageSize * pageNo)
    |> List.take pageSize
3 Likes

I’m a fairly commited elm-ui user and would be super-happy to try out 2.0.

1 Like

Perfect! I’ll add you to the list

I’m also interested in trying out the alpha of elm-ui v2!

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.