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.
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With