Applying a filter with a large member selection blocks the browser for several seconds. The duration scales with the number of selected members.
Browser-profiling: the blockage is one synchronous task of 6,030 ms inside the Apply click handler. 5,973 ms of that, 99 percent, is spent in a single Array.prototype.some() in flexmonster.full.js. Our own code accounts for 23 ms across the whole profile. No request is involved — select only starts after the freeze has ended and returns in 2 ms.
The method is A3() in 2.9.136:
A3(c,d){return 0==d.length?!1:d.reduce((g,k)=>{
if(c.some(n=>n==k))return g;
const m=this.Ac.ya(k).children;
return g&&this.A3(c,m)},!0)}
It is called with the selected member ordinals and all top-level members of the hierarchy, i.e. the "if everything is selected, the filter can be dropped" check. c.some(...) is a linear scan of the full selection list per visited node, so the cost is O(#members x #selected) — on a flat hierarchy with tens of thousands of members that is hundreds of millions of comparisons. The reduce also doesn't break once the result is determined.
We understand the intent: dropping the filter avoids sending a large member list and makes the query cheaper. But the cost is paid on every apply, including when the answer is "no", and the query it saves took 2 ms in our profile. In the common case of "many but not all members selected" the full price buys nothing.
Two questions:
We would rather not patch node_modules locally. Note also that we cannot simply skip the call on our side — the return value appears to feed internal filter state, and the whole sequence runs inside your click handler before any event we could hook into.
Hello Lukas,
Thank you for reporting the issue.
You are correct that the check used to decide whether to drop the filter can be improved, and your suggestions sound reasonable.
Our team will take a look at the described behavior and provide a fix with our minor release with the ETA September 14th. We will notify you about the release.
In the meantime, it would help us a lot if you could share a small example (a dataset or a way to reproduce the freeze) where the issue occurs. That way, we can validate the fix in your actual scenario and ensure it resolves the freeze for you before we ship it.
Looking forward to hearing from you.
Kind regards,
Nadia
Hi Nadia,
thanks. Attached is a self-contained repro: one HTML file, Flexmonster from the CDN, no backend and no real data. It generates a flat field id with 30,000 distinct members and keeps the grid at 3 rows so rendering cannot be confused with the effect. Two paths:
id, select all, uncheck 2–3 members, click Apply.setFilter("id", { members: [...25,000 of 30,000...] }) — same filter builder, no clicking.Both block for seconds, in one synchronous task, almost entirely in the some() inside the recursive check. MEMBER_COUNT and SELECT_COUNT at the top of the script scale the effect.
Our production setup uses a custom API data source, but the effect is client-side only and depends on the member count and the selection size, so the JSON source reproduces it identically.
Two notes for validating the fix:
false.setReport / slice.reportFilters, not only on user interaction.Kind regards,
Lukas
Hi Lukas,
Thank you for providing the steps for reproducing the issue!
It looks like the file was not attached to the comment. Could you please re-attach the file (or share it via a link) so we can use it to validate the fix?
Kind regards,
Nadia
Ah yes, sorry for the inconvenience.
Hi Lukas,
Thank you for sharing the file!
This gives us everything we need to check the fix. We will let you know once the release is ready.
Do not hesitate to contact us if other questions arise.
Kind regards,
Nadia