-
Notifications
You must be signed in to change notification settings - Fork 929
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
Use baselayerchange/overlaylayerchange instead of layeradd/layerremove #5474
base: master
Are you sure you want to change the base?
Conversation
|
I also saw a problem in PR: when you click the Map Data checkbox, the cookie with the current location is no longer updated |
a359de9
to
a32249e
Compare
Okay, firing events from I also replaced |
a32249e
to
5b37b54
Compare
With the latest changes I was able to render Lake Huron locally in a reasonable amount of time (<20s, including 4.5s API response time; 455k nodes). Also map data display is extremely fast now (e.g. 100ms instead of 3s). That is definitely a significant speed-up. Ideas for follow up PRs:Furthermore, switching from XML to JSON has improved the response time from 20s to 8s (both values include 4.5s API time). For reference, I've uploaded the quick hack here: https://gist.github.com/mmd-osm/d45ff3b4f41908b1c075d70d1b6fdebe (edit: added fetch based + error handling alternative). We should think about adding some error handling: |
Jquery uses In a next step switching to |
5b37b54
to
30403cb
Compare
We probably need to fire If we follow the same principles as |
Do I understand correctly that you are talking about the current behavior of the website, and not after PR? At least in Firefox, changing |
@AntonKhorev 's comment wasn't exactly clear to me either. I think it's the following. Note that once you change the layer in the URL (in the example below from "C" to "H"), the share link "layer" attribute is updated accordingly: This doesn't seem to work anymore with the changes in this PR. Besides, there may be some timing issue in the current code, as the behavior is not 100% reproducible for me, even today. Sometimes the map layer changes along with the share link, in other cases, the old layer is still shown. |
Ah, I understand. I only tested changing the letters that represent the overlay (D/N/G). Changing the letters that respond to tile layers works now. PR broke it. I'll try to fix it |
Leaflet ships with a layers control which lets you switch between layers. That thing is responsible for firing
The problem is that our layers menu is not the only thing that can switch layers. All other places where layer change happens need also to fire Similar story with UPD: we're doing this wrong, see the following comments... |
30403cb
to
ad9dcfe
Compare
Okay, I added the |
@@ -116,6 +116,7 @@ L.OSM.Map = L.Map.extend({ | |||
} else { | |||
this.removeLayer(this.baseLayers[i]); | |||
} | |||
this.fire("baselayerchange", { layer: this.baseLayers[i] }); |
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.
This fires the event for every possible base layer. It's supposed to be fired only for the layer that became visible, that's how it works in leaflet.layers.js
.
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.
Implemented a check that there is already a layer on the map. But the code doesn’t look so attractive anymore, so it might be better to add add
/remove
handlers for all base layers. For some reason the naive addition in initialize()
does not work yet
layer.on("add remove", function () {
this.fire("baselayerchange", { layer: layer });
})
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.
You could put this.fire ...
next to this.addLayer ...
, that's one extra line of code. (with a caveat that if you're switching to the same layer, baselayerchange
still fires; if that's wrong, our layer menu is also wrong)
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.
Yes, looks like our layers menu is wrong. Leaflet's layer selector doesn't fire baselayerchange
if you clicking an already active layer, and if you add an already added layer using map.addLayer
, layer events also don't happen.
ad9dcfe
to
f10083a
Compare
…e for speed up Map Data layer render
f10083a
to
12fee32
Compare
this.addLayer(this.baseLayers[i]); | ||
} else { | ||
baselayerChanged = this.hasLayer(this.baseLayers[i]); |
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.
baselayerchange
is supposed to be fired once for the layer that became visible. It's not supposed to be fired for removed layers. See that null
in Leafet code?
https://github.com/Leaflet/Leaflet/blob/c511e66c20dce06ac05c43cf287b3ecdba00d924/src/control/Control.Layers.js#L317-L319
"This event would be triggered after the other layer events, and it would include a layer property set to the resulting base layer." Leaflet/Leaflet#1064
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.
So the next handler also violates this expectation?
openstreetmap-website/app/assets/javascripts/leaflet.layers.js
Lines 62 to 71 in b45eb03
input.on("click", function () { | |
layers.forEach(function (other) { | |
if (other === layer) { | |
map.addLayer(other); | |
} else { | |
map.removeLayer(other); | |
} | |
}); | |
map.fire("baselayerchange", { layer: layer }); | |
}); |
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.
The answer to the above question was yes but it probably didn't affect anything. However if we start using baselayerchange
in more places, it might. For example, this code, if rewritten for baselayerchange
wouldn't work correctly, if it expects this event to happen like Leaflet would fire it:
openstreetmap-website/app/assets/javascripts/index.js
Lines 208 to 216 in b45eb03
map.on("layeradd", function (e) { | |
if (e.layer.options) { | |
var goal = OSM.MATOMO.goals[e.layer.options.layerId]; | |
if (goal) { | |
$("body").trigger("matomogoal", goal); | |
} | |
} | |
}); |
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 "baselayerchange overlaylayerchange"
will work in this place (provided that baselayerchange overlaylayerchange
is firing in all places that the layer is added)
Do we fix |
Description
This is fix #5466 After merging openstreetmap/leaflet-osm#43 flame graph looks like this:
https://share.firefox.dev/4a2Wc9Z
Most of the time is spent on two handlers that update information about the current location and elements in the right sidebar.
Unfortunately, replacing
layeradd layerremove
withbaselayerchange overlaylayerchange
(#5466 (comment)) is difficult, since in addition to the Map Data layer, other elements may be displayed on the map. For example, the currently selected object on the map. It is not clear how to separate changes to Map Data objects and changes to the selected element. It is necessary to track changes in the active element, otherwise at least the Edit button will break.Therefore, I implemented a little ugly, but safer in terms of breaking business logic. When adding the Map Data layer, I set the pause flag in the slowdown handlers. While the Map Data is rendering, the user cannot interact with the interface, so it seems safe to pause the event handlers.Total 15s vs 0.5s when rendering 5000 elements.
https://share.firefox.dev/4h4IK7C