> It is generally considered that anything that takes more than about 50ms will produce a noticeable jank in GUI smoothness
Google believes the number is 100ms: https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-performance/rail#response-respond-in-under-100ms
> 400ms is pushing it really, but it all depends on just what is expected from the user action and the user.
Yes, 400ms feels a bit slow. We _could_ filter out _less_ elements to make the hints appear faster, but then _more_ hints would be created. The time saved would then be more than lost when the user tries to find the correct hint in a sea of irrelevant hints. Also, the more hints the _longer_ hints, so users would also spend more time typing. This is a tricky trade-off.
> getClientRects() is probably a lot slower than simply using the bounding rectangle.
No. We used `getBoundingClientRect()` initially, but had to switch to `getClientRects()` to position the hint for line-wrapped links in a sane way. When doing so I was worried about performance, but my tests showed no difference. That might not be so strange, though, because many times `getClientRects()` returns a single rect, identical to the one returned by `getBoundingClientRect()`. And considering that `getBoundingClientRect()` can be "polyfilled" using `getClientRects()` , perhaps `getBoundingClientRect()` uses that internally. But enough guesswork and "probably:s" now.
> Restricting the list of nodes by tag name will give a big boost compared to filtering all nodes, but anything else you can think of to filter the list up front would be a help.
I can't restrict the nodes by tag because any type of element might be clickable, because of JavaScript. (Clickability is determined later by inspecting each element.)
I also found that checking if the elements are inside the viewport before filtering for clickability is significantly faster. It was before I reordered that I got the mentioned slowdown in my last comment.
> Its amazing what you can get done in JavaScript in a few ms, but don't kid yourself that it is as fast as compiled C code using a fancy matrix manipulation algorithm.
That's why I came here in the first place. I didn't want throw `nodesFromRect()` out of the window, because I was too thinking of the performance of C/C++, having access to things not exposed to JavaScript, etc.
When we first switched to `nodesFromRect` there was a significantly noticeable performance increase. However, that was some time ago. Looking back at the code with fresh eyes I realized that the same performance boost might be done with a slight code reorder. And as it turned out, I was right!
`nodesFromRect()` might be faster. I don't now. But it doesn't matter. Because in VimFx the difference isn't noticeable.
---
Thanks for all your responses! My immediate problem has been resolved. I'm still interested in knowing how `nodesFromRect` _is_ supposed to work though, purely because of curiousness :)