tether
tether copied to clipboard
Huge performance issues!
Hello,
I've been working with tether
and tether-select
, and decided to made a quick performance test using Chrome's timeline tab..
Looks like there's a lot of painful operations going on; I made a test with ~ 20 custom <select>
within the page, and every frames takes ~ 65ms to render. This is way too huge!
Every frame should be ~ 16ms.
We can see here that for every <select>
element on the page, the functions are being called:
-
position
-
cache
-
getScrollBarSize
Theses functions cost a lot because of;
position
(line 1003):
if (document.body.scrollHeight > window.innerHeight) {
getScrollBarSize
(line 172):
var widthScroll = inner.offsetWidth;
Kinda related to this issue from tether-select
: https://github.com/HubSpot/select/issues/43
I really think this has to be fixed. Just to be sure, I do not have any other onscroll
events; everything on the screenshots come from tether.js
.
Thanks for such a thorough look. We’ll definitely be looking into this. cc @zackbloom
Sadly this isn't uncommon when there are developers lacking sufficient knowledge in browsers and performance. yes, Tether is awesome and I love it, and been using it for a long time, but.. the code is an absolute horrible mess :(
A quick solution would be using fastDOM everywhere in the code (this is have huge benefits, but is a very tedious thing to incorporate since there are tons of lines of code which touch the DOM without apparent order),
First of all I think it would be nice to cache the scrollbar size widthScroll
variable somewhere else, so there's no look-up for the offsetWidth
on every scroll event fired.
I guess this would also work for the position detection: cache the document.body.scrollHeight > window.innerHeight
test somewhere and call it again only on resize.
@baptistebriel I would welcome a PR to make Tether more efficient. Can the result of getScrollBarSize
be cached without introducing positioning bugs? I see that this value currently is nominally cached, but clearCache
is called at the top of position
, which is the 'scroll'
event handler.