Loading 1100 clickEl's is very slow
See original GitHub issueI have a list of 1100 users and I tried to make a button
for each one (using clickEl
) that returned the userId to a parent element, which I would use to jump to a new route. But it’s extremely slow loading that many click elements. It could handle a couple hundred well, but approaching 1000 the performance really plummets. Once they load up, it’s pretty responsive, but loading them take at least 10 seconds.
For now I just made a fake button function that uses a href
instead of Concur’s events machinery:
linkButton :: String -> String -> Widget HTML ()
linkButton label url = el_ E.a [ A.href . JS.pack $ url ]
$ el E.button [ A.class_ "pure-button" ] [ text label ]
which is really fast and fine for now since I’m just jumping to an URL, but at some point I’m sure it would be nice/essential to be able to use clickEl
’s or some other event listener for a big list.
Issue Analytics
- State:
- Created 6 years ago
- Comments:20 (14 by maintainers)
Top Results From Across the Web
Windows 11 - Right-Clicks Keeps Loading Fix - YouTube
For more information, check out this guide:https://www.techy.how/tutorials/win11-rightclick-fixA short tutorial on how to fix the issue when ...
Read more >right click takes forever to load - Microsoft Community
It can cause a context menu to be extremely slow or freeze when you right click to open the context menu. You can...
Read more >Loading tables very slow using SQL developer — oracle-tech
Around 1100 tables takes 10minutes to load, when I do select * from user_tables, this is very fast from client. The same is...
Read more >The Scanning Speed Is Very Slow | ScanSnap Help - PFU
The speed of scanning documents may slow down depending on your system environment. · Click the [Scan] button at the top of the...
Read more >very slow load of printer dialogue box - Apple Community
very slow load of printer dialogue box · 1. Running Repair Disk Permissions located in Disk Utility. If no good then; · 2....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hah well, it’s really a new feature, and I’m glad it solved your problem! The changes are all here - https://github.com/ajnsit/concur/commit/78ac2b224d1d2454ad4ddb014bc48950cc46481a.
Gist
Basically I added support for blocking IO to Concur. Then used it for a very common use case where async io was a bottleneck.
Background
All actions like
liftIO
andliftSTM
are run async, and are effectively full widgets.A common pattern with a lot of widgets (like
button
) was to useliftSTM
to procure aNotify
(a very quick operation), and then used the Notify to link the view click and the handler. This means that a singleButton
was effectively a sequence of two widgets,liftSTM
and then the actual button UI.Also all widgets are encapsulated and run async, and any changes to the widget tree causes a full dom render cycle (albeit with virtual-dom diffing).
Problem
So when a
button
is first added to the widget tree, it actually renders theliftSTM
widget (i.e. no UI), which quickly finishes, and then renders the actual button UI.When you add two
button
s in quick succession, the firstliftSTM
widget renders and finishes, then the secondliftSTM
widget renders and finishes, and then the firstbutton
UI renders, and then the secondbutton
UI renders. The order can vary depending on how long it takes for aliftSTM
to finish.You see where this is going.
With 1100
button
widgets, you have 1100 quick dom rerender cycles in a row which takes ~10 seconds on your machine, including the overhead for all the rapid widget sequencing.Solution
I added a special function called
awaitViewAction
which provides aNotify
to a widget, but does so with blocking IO. Blocking IO prevents DOM updates so cannot be used for long running IO actions, and hence I am reluctant to make it available to clients. However this specific use case of constructing aNotify
in STM is guaranteed to be extremely short and can safely be exposed to client widgets.With this change, on adding 1100
button
widgets, the IO actions are quickly run in succession without touching the DOM, and finally each widget constructs its own UI which is populated into the DOM at once (one render total for all 1100 buttons). The same as what happens with your “fake”linkButton
code.Okay I’m pretty certain I understand why this is happening. Will push a fix soon-ish.