Skip to content
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

Panning the map is jaggy and slow. #1727

Closed
viesturz opened this issue Aug 23, 2013 · 11 comments
Closed

Panning the map is jaggy and slow. #1727

viesturz opened this issue Aug 23, 2013 · 11 comments
Labels
performance Optimizing for speed and efficiency

Comments

@viesturz
Copy link

Steps to reproduce:

  • open a editor with around 100 objects or so.
  • drag the map around and let go.
  • map update takes about 0.5 sec on core i7.
  • the lag gets higher as object count increases, easily getting to few seconds.
  • this really disrupts workflow, making clicks unreliable and lagging visual feedback until the update is finished.

A quick profile shows this is mostly due to SVG updates being slow.
Have you considered using canvas instead? Kinect.JS?

Tested on: chrome, firefox, win8, x64.

@jfirebaugh
Copy link
Member

Hmm, that's definitely well below the level of performance we expect, and most people see, on an i7, especially with Chrome. Can you try a couple of diagnostics?

  • What's the URL for the area you're editing?
  • Any different in an incognito window?
  • Gist the output of chrome://gpu

@viesturz
Copy link
Author

URL: http://www.openstreetmap.org/edit?editor=id#map=18/56.83258/24.51959
Same in incognito.
Gpuinfo all green:

Graphics Feature Status
Canvas: Hardware accelerated
Compositing: Hardware accelerated on all pages and threaded
3D CSS: Hardware accelerated
CSS Animation: Accelerated and threaded
WebGL: Hardware accelerated
WebGL multisampling: Hardware accelerated
Flash 3D: Hardware accelerated
Flash Stage3D: Hardware accelerated
Flash Stage3D Baseline profile: Hardware accelerated
Texture Sharing: Hardware accelerated
Video Decode: Hardware accelerated
Video: Hardware accelerated

@viesturz
Copy link
Author

Is there a copy of non-obfuscated ID I could debug?

@viesturz viesturz reopened this Aug 24, 2013
@viesturz
Copy link
Author

Another bad behavior (easier to test):
Try panning in multiple short successive swipes.
The map hardly moves at all, moving below 10% of each swipe distance.
Even empty map is super laggy and gives me around 30-50% of the drag distance.

Still win8, core i7, using mouse.

@jfirebaugh
Copy link
Member

Is there a copy of non-obfuscated ID I could debug?

Sure, clone the repository and open index.html

@tmcw
Copy link
Contributor

tmcw commented Sep 17, 2013

@viesturz any further profiling data you can share?

@viesturz
Copy link
Author

Finally got some time to play with this.
Using default ID view (Washington), master from today.

#1 Zoom out a bit and move map to a new location, map data loads incrementally in chinks over several seconds. Map freezes whenever data is received.

Here is a Chrome "Flame Chart" on a typical load event, totaling 250 ms.
id-load

Observations:

  • loading and parsing could be moved to a web worker (60ms)
  • full redraw is done after each chunk is loaded (150ms). Is incremental redraw possible?
  • tagClasses is called very frequently and takes 33% of the redraw.
  • contributors update calls history.intersects with visible bounds that takes another 40 ms. Might be done asynchronously.
  • line 50 in areas.js/drawAreas takes 16ms by itself: areas = d3.values(areas).filter(function hasPath(a) { return path(a.entity); }); The hasPath function takes 99% of that time, constructing actual paths.
  • conversion to geoJson and back adds some time too.

#2: start drawing a line with 1 segment and move mouse around so the segment moves with it.

I see 30/30% distribution between browser rendering SVG and javascript. It's really wrong and should be more like 30/1 %. There is too much computation going on just to move a single point on screen (or even replace the whole line).
Adding more points adds more javascript load quickly, going to 30/70 % at around 40 points.
The main functions are iD.difference and tree.intersects.

Viesturs

@jfirebaugh
Copy link
Member

loading and parsing could be moved to a web worker (60ms)

We've considered using web workers; the blocking factor is the fact that the DOM APIs used to parse the OSM API XML response are not available in web workers, and the OSM API does not yet support JSON.

full redraw is done after each chunk is loaded (150ms)

It's actually an incremental redraw -- the if (extent) case here.

tagClasses is called very frequently and takes 33% of the redraw

We've spent some time optimizing tagClasses in the past; it's not currently looking like a bottleneck in my profiles (<1% total time).

contributors update calls history.intersects with visible bounds that takes another 40 ms. Might be done asynchronously.

True, though it wouldn't reduce the overall time, just spread it out over more turns of the event loop.

The hasPath function takes 99% of that time, constructing actual paths.

The resulting path is cached and used several times over the course of rendering -- it's work that has to be done at some point. That said, since we're not currently using any advanced d3.geo.path features like resampling or clipping, we might save a few % by iterating nodes directly rather than going through asGeoJSON + d3.geo.path. Though asGeoJSON is now cached, so that part will only be a win on initial draw.

It's really wrong and should be more like 30/1 %.

I'd love to get there, but I think you're underestimating the amount of processing that iD does to support interactions like fading labels in and out, showing and hiding vertices on hovered ways, etc.

@pnorman
Copy link
Contributor

pnorman commented Oct 11, 2013

We've considered using web workers; the blocking factor is the fact that the DOM APIs used to parse the OSM API XML response are not available in web workers, and the OSM API does not yet support JSON.

Would it help if the map? call returned JSON, even if you had to do XML for diff uploads?

@jfirebaugh
Copy link
Member

Definitely. With JSON it might not even be necessary or beneficial to use a web worker.

@jfirebaugh
Copy link
Member

Closing here. Path calculation was optimized in 1.3, other avenues covered by #1498.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Optimizing for speed and efficiency
Projects
None yet
Development

No branches or pull requests

4 participants