htmx
htmx copied to clipboard
`handleAttributes()` slow on large pages (Firefox)
On large HTML pages (20 MB+), we found Firefox to be slow to swap large DOM trees. After doing some profiling, the culprit seems to be handleAttributes()
, which iterates across all elements with an ID. Given that a large number of our DOM elements have IDs, some iterations of handleAttributes()
took over a second on my 2019 Macbook Pro.
Chrome wasn't found to have the same performance issue.
I couldn't really understand what handleAttributes()
does or how often it should be called, but reducing the number of elements with IDs helped fix this issue.
I think a large amount of manipulation work is required to avoid replacing DOM nodes with identical nodes, and I think this is because CSS transitions wouldn't work without them. If this is the case, it would be handy to have a configuration option that allows you to choose between replacing all nodes (and disabling CSS transitions) or preserving nodes where possible (and having a small performance cost). I'm probably missing something here though!
Could you shed some light on what might be happening here? Thanks for all your help in advance!
handleAttributes
is used to enable CSS transitions: it takes the old values of attributes for the new content and swaps them in, then swaps in the new values.
Reducing the number of things w/ IDs will definitely help. We could also add the ability to disable this for large swaps.
@1cg - The built-in support for transitions is super-cool but I rarely use it in my code. Perhaps this could be optional as in hx-transition="true"
or as an extension, or as a setting in htmx.config
? It might be something to consider for htmx 2.0.
@jonnyarnold - 20MB of HTML is pretty huge. First, congrats on getting that much to run anywhere :) Second, we've made demos on infinite scrolling that might help you to lighten the load on your browser, at least initially (and, depending on your specific use cases, of course). I had even worked up one that would trim (then reload) pages from the top and bottom of the result sets, so that only the current few "pages" were ever kept in the browser. Let me know if something like this would be helpful :)
@1cg - Being able to disable this would be the ideal situation for us!
@benpate - Yeah, I thoroughly appreciate it's a silly-big HTML document 😅 Pagination is likely to be the solution in the medium term: having links that link to the middle of the document complicate things, but it's not insurmountable. Thanks for the tip 🙂