-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance: use event delegation #319
Conversation
Ah, I may need to update the tests |
Hi @Indigo744 , Wow, indeed its a big one. Thanks a lot for it, I was having in my mind this issue regarding the huge number of events added by Mapael since a long time, but never took the time to dive into it ! I will take the necessary time to look at your PR and I will keep you informated within the next few days ! |
5f1bd73
to
74f5d97
Compare
Added delegation for custom events! |
Wow thanks ! I keep you informed ASAP for the review ! |
js/jquery.mapael.js
Outdated
self.$map.on("mouseover." + pluginName, "[data-id]", function () { | ||
var elem = this; | ||
clearTimeout(mapMouseOverTimeoutID); | ||
mapMouseOverTimeoutID = setTimeout(function(){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing space between ) and {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
js/jquery.mapael.js
Outdated
self.$map.on("mousemove." + pluginName, "[data-id]", function (event) { | ||
var elem = this; | ||
clearTimeout(mapMouseMoveTimeoutID); | ||
mapMouseMoveTimeoutID = setTimeout(function(){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing space between ) and {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
js/jquery.mapael.js
Outdated
|
||
/* Handle tooltip position update */ | ||
if (elem.tooltip !== undefined) { | ||
console.log(elem); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
console.log() should be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see it actually... Did you check the latest rev?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Indigo744 ,
Wow, very ... very huge work for a great improvement upcoming !
I have reviewed your PR, but commit by commit, I hope you will be able to read all the comments (some of them are obselete as you have fixed the issues in the next commits, like the trailing console.log() for instance).
All seems to work, except that the "onhover" (for instance to display the tooltips) behaviour is now jerky. I think this is due to the setTimeout() within the mouseover event handler ?
I think its ok to have a timeout before displaying a tooltip on an area or a plot (this is the current behaviour). But the tooltip should not be jerky when it is already displayed and the user is moving the cursor within an area.
js/jquery.mapael.js
Outdated
var id = $elem.attr('data-id'); | ||
var type = $elem.attr('data-type'); | ||
|
||
if (type === 'area' || type === 'area-text') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this if/elseif/elseif condition could be simplified with :
typesMapping = {
'area' : 'areas',
'area-text' : 'areas',
'plot' : 'plots',
'plot-text' : 'plots',
'link' : 'links',
'link-text' : 'links'
};
self.elemClick(self[typesMapping[type]][id]);
(maybe typesMapping could be more global, as this if/elseif/elseif pattern is repeating in each event handling functions).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really good idea! I just committed the change.
js/jquery.mapael.js
Outdated
@@ -1954,7 +1952,7 @@ | |||
if (elem.tooltip.overflow.right === true) { | |||
tooltipPosition.left = mouseX - self.$map.offset().left + 10; | |||
} | |||
if (selem.tooltip.overflow.bottom === true) { | |||
if (elem.tooltip.overflow.bottom === true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that you have fixed this typo twice ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahah yes indeed!
I've updated as per your recommendation =) I tried to create enough small commits so you can review one by one. But in the end, maybe we should use the "squash and merge" option of GH. What do you think? |
…o event_delegation
Since we are already talking about v3 (plugin related), I'm wondering if we should postpone this evolution to the next major release? I am afraid it may break on some people who has weirdly override some event handlers on each element... What do you think? |
Hi @Indigo744 , Thanks for the fixes and for having separated the work in small commits, it helped a lot for the review ! (I agree for the squash when we will merge it with the master branch). Have you some weirdly override cases that will not work anymore when this PR will be merged ? I think that if some user extend some of the internal functions of Mapael, they should do this with full knowledge of the facts.Otherwise, each minor change of any internal function interface should lead to a new major release of mapael. |
Nah I don't have any weird override cases ^^ but I was trying to imagine what could be the implication. I think you are right, and the benefits can be important for users with lots of plots. As a side note, I was wondering if we should put the filtering Timeout values as a variable so user can override them if needed. |
I think it could be indeed a good idea to make the timeout delay an internal variable to allow overriding. However, I think we shouldn't expose it as an regular option as the great majority of users will not need to override it. |
…nto event_delegation
Ok, this one is quite big.
Until now, we attached to each area/plot/link node the following event listeners:
This can become quite a lot for big maps with lots of elements.
The solution is actually quite simple: use event delegation!
Basically, instead of attaching all event listener per node, we attach only one event listener to the container, and filter the child element with delegation.
More information: http://api.jquery.com/on/ and https://learn.jquery.com/events/event-delegation/
So the modifications are:
$().on()..
)initDelegatedMapEvents()
and dispatch relevant actionFor now, I haven't touched the way the customeventHandlers
works. They are still attached to each node according to the user option. What do you think?Here is a test using one of the example with lots of plots and tooltips
Before:
1113 events listeners, 21 MB JS heap
After:
4 events listeners, 15 MB JS heap
This may help for #304
I've checked all example without finding any regression. But I'll let you review this ;-)