Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selectorator.js - selector of all hidden elements on page


I'm implementing heatmap to display all users click on my page using heatmaps.js by Patrick Wied. Heatmap is loaded from collection of "datapoints" for each element. But it takes too long to load....
Issue desc.:

Each datapoint has X,Y coordinates and selector (retrieved using selectorator.js) of HTML element on page. Currently i am getting about 5k points for each page and I need to check if some elements are not hidden so we won't show heatmap for hidden elements.

Currently I am using:

element = $(data.points[i].Element);
element.is(":hidden"))

but this takes about 7 seconds to check all those points which is quite long. I have run out of ideas how to avoid/optimize this issue.

Datapoint detail:

Element: #pageData > tbody > tr:eq(3) > td:eq(4) > a:eq(0)
Y:0.6546159
X:0.4444231

Pseudo script flow desc.:

FOREACH(point in allDatapoints)
{
 ...
   calculation of some parameters needed to show on heamapat
 ...
  if (point.element.is(":hidden"))
  {
    continue;
  }
  pointsToDisplay.push(point)
}

I've also tried to get selectors of all hidden elements but GetSelector() in selectorator.js and then just go through that array but it takes almost same time as is(:hidden) function.

I hope this makes sense.

enter image description here

enter image description here

Fact: Getting selector of an element might take a little time, but reverse process(getting and element based on selector) takes almost no time. -> so I can not simply send array of selectors of hidden elements and filter those which would be a lot faster.

like image 932
Kamza_ Avatar asked Dec 14 '15 09:12

Kamza_


1 Answers

looking at the source of selectorator seems to indicate it generates selectors by using an index; i.e. pageData > tbody > tr:eq(3) > td:eq(4) > a:eq(0)

Now, retrieving the element via that selector looks quite complicated (i assume that something will need to parse it, and execute the selector to retrieve the actual element;

I'm guessing here that that is what is taking so long, as I said in the comments, a profile will really help.

So, without trying to fix this exact problem, can you rather save the display property of the element? this will eliminate the need for checking via jQuery.

Example for manually checking

element = $(element);
while (element.tagName.toLowerCase() !== 'body') {
    if (element.style.display === 'none') {
        return false;
    }

    element = element.parentNode;
    if (!element) break;
}
like image 182
epoch Avatar answered Oct 16 '22 20:10

epoch