Leaflet.TimeDimension
Leaflet.TimeDimension copied to clipboard
Performance with many markers
I have a performance issue when Leaflet.TimeDimension
shows many markers. To demonstrate this I created a jsbin which draws circleMarkers on a single canvas:
http://playground-leaflet.rhcloud.com/rus/1/edit?html,output
If you have a look at the time display of the player UI element you can see that the performance initially is good. It significantly drops when you move the slider to the end of the timeline.
For my use case I need to show ALL previous markers (as in the jsbin example). I suppose that Leaflet.TimeDimensiom
currently keeps some stateful information for each marker it displays which results in this performance drop. Can you help me locating the according bottleneck?
I would expect that Leaflet.TimeDimension
only draws the according marker to the canvas and then forgets everything about it when it advances to the next step.
For each time, it will recreate a new layer that contains only the features that are returned by _getFeatureBetweenDates
see L.TimeDimension.Layer.GeoJson
Returning null in that function will remove the feature. One improvement will be to use a LineString instead of a feature collection. You can specify a time for each coordinates along the path. This is what is used in the Hiking example.
In any case rendering 2000 markers in leaflet is pretty intensive. They are all rendered as div. If you use a linestring, leaflet will render the path in svg or canvas.
In the linked jsbin I already set window.L_PREFER_CANVAS=true
for perfmance reasons so that all markers are painted in the same canvas without adding separate divs. Unfortunately this didn't help.
Also as I need some additional properties for each geoposition I unfortunately have to use feature objects and cannot switch to LineString
.
For me it looks as if I the _update
function should be tweaked so that it does not create a new layer with all the previous features on each tick but simply adds the new marker (of the current tick) to the already existing _currentLayer
. However if the user manually moves the slider of the player control a new layer with all previous markers needs to be created.
Does this sound reasonable to you?
You can try that, but the actual code deal with one other thing : remove obsolete features. Not useful in your case but still allow to display only the last 5min for example. Don't forget the case when the user come back in time. you need to remove all future points. LineString are something else because they are not add/removed their path is modified.
You can still go the shorter path and change this function only for your need.
This is complex to optimized, and I feel you will end up with some sort of a reverse map time->feature
PS : profiler on chrome says it's spending 46% of time in drawing strokes. That may be better with Leaflet 1.0
Update: I already did a quick test with the new strategy which looks promising: There isn't any notable performance drop with 2000 markers.
My strategy would be as follows:
When minTime
is 0
and the current time directly follows the last time which has been displayed (i.e. during playback but not when the user jumps back or forward in time) the new feature gets added to the already existing _currentLayer
instead of removing the previous _currentLayer
and readding a new layer with all the previous markers.