htmx
htmx copied to clipboard
v1.9.x: massive performance degradation on big pages
Hi there,
After upgrading htmx from 1.8.x to 1.9.x we experienced some major performance issues on big pages performing many htmx requests.
Firefox Profiler showed me the culprit: this line. Nothing surprising here: our page is quite big, and it's background-loading some new stuff quite often. At the end of each AJAX request, at htmx-settle time, an XPATH query is run against the whole DOM to find some hx-on
elements (we don't use this feature, we have no hx-on
on this page).
since you mentioned hx-on
: did you mean this line? https://github.com/bigskysoftware/htmx/blob/v1.9.0/src/htmx.js#L1887
function processHxOn(elt) {
var hxOnValue = getAttributeValue(elt, 'hx-on');
Ah sorry I forgot to target a tag, thanks @hastebrot for pointing that out. No it's that one, introduced in v1.9.3. It performs a wild XPATH query.
Performance got back to normal (i.e. great) after rollback to v1.9.2.
@David-Guillot Would you mind linking with a permalink? The link you have now is to an empty line, presumably because that line number is something different in the current master
branch.
EDIT: got it
Shouldn't the xpath expression that looks for the hx-on
be prefixed with a period (.
)?
To quote from the documentation of document.evaluate
:
Further optimization can be achieved by careful use of the
context
parameter. For example, if you know the content you are looking for is somewhere inside the body tag, you can use this:
document.evaluate(".//h2", document.body, null, XPathResult.ANY_TYPE, null);
Notice in the above
document.body
has been used as the context instead of document so the xpath starts from the body element. (In this example, the "." is important to indicate that the querying should start from the context node,document.body
. If the "." was left out (leaving//h2
) the query would start from the root node (html
) which would be more wasteful.)
In HTMX's source, I think elt
is meant to be the starting point of the query, but because the period is missing, the entire document is searched instead.
By the way, the fallback code that emulates document.evaluate
if that function is not available also scans the entire document, it does nothing with the given elt
parameter.
Hey @David-Guillot I am looking at this perf issue now
Hey @David-Guillot we have a pr from @Telroshan w/ a fix for this:
https://github.com/bigskysoftware/htmx/pull/2060
it looks good to me so I'm going to integrate in into dev
as part of 1.9.10. Would you be willing to try out a pre-release version to verify that it addresses your perf issues?
I guess it's already available here [1] for testing.
[1] https://cdn.jsdelivr.net/gh/bigskysoftware/htmx@dev/src/htmx.js
Hey @1cg , yes I can confirm the dev version fixes the issue! Thanks @Telroshan for the fix :clap: . This issue can be closed as soon as #2060 is part of a release :+1:
@David-Guillot can you test against the current dev branch again? We added the ability to use only dashes (JSX doesn't like colons) and made the query slightly more complicated. I want to make sure it doesn't affect you again.
Hi there,
I can confirm that v1.9.10 is still blazing fast :zap:
Closing this :tada: