Leaflet/Leaflet — pull request #2755 by fab1an (2014-06-21 16:46:12+00:00)
Title: refactoring of events, it should be about 4 times faster now

I reworked the events-system, this way it's about 4 times faster. Removing listeners for 3000 layers took 160ms on iPad, now it takes ~40ms.

Most performance comes from these observations:
* concatenating object-keys is really slow: http://jsperf.com/member-associative-array-syntax-vs-dot-syntax/3
* concise syntax for initializing object-properties does too many lookups: http://jsperf.com/short-object-init

Remarks:
* I removed the second code path with the simple arrays for simplicity's sake. The memory-overhead by using a couple, or even thousands of simple objects is negligible. If we want to improve in that direction GC-pauses, e.g. because of creating and destroying hundreds of thousands of L.points during projection are the larger problem.

* In the old code there was a bug, if you removed a no-context listener, event[type] would still be declared and listens would return true, even if no listener would be in the array anymore.

* There's another bug in the old code, which is in the new one as well. The whole "don't fire during removed" doesn't work if no function is supplied during removal and all listeners for the type are removed. I didn't change it for now.

* There were a couple of functional differences between the with and the without/context listeners. In the old code you could add the same event/fn pair without context twice, which wasn't possible with a context.

* I found this commit https://github.com/Leaflet/Leaflet/commit/dcb6f74ef5c5c222de85655e1e39a6be506049f4 but can't understand how it guarantees the execution order of events. Order of property traversal is never guaranteed in JavaScript!