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

rendering performance brainstorming #1498

Closed
jfirebaugh opened this issue May 17, 2013 · 3 comments
Closed

rendering performance brainstorming #1498

jfirebaugh opened this issue May 17, 2013 · 3 comments
Labels
performance Optimizing for speed and efficiency

Comments

@jfirebaugh
Copy link
Member

This is what rendering DC at z16 looks like:

flame

(Flame Chart profile in Chrome Canary is awesome.)

Rendering areas dominates, followed by labels, then lines. Points and vertices are not significant contributors.

The one thing that sticks out (orange rectangles) is streaming geometry through d3.geo.path() in order to calculate areas and generate SVG path strings. This is hard to cache because it depends on the current projection scale and translation.

Options:

  • Pull in d3.geo streaming code and hand-optimize. We could do manual inlining and skip some steps we don't need (preclipping, resampling). Probably a significant amount of work for at best ~2x speedup.
  • Move path calculation to web-worker. This would likely increase overall rendering time but decrease the amount of UI stall time. It would also introduce significant asynchonicity and therefore complexity to the rendering model.
  • Avoid full rerenders on simple pans. Instead, iD would preserve the CSS-based translation that's used during the pan drag, and continue to project coordinates based on the map starting location. Rerendering would only need to consider features that entered or left the viewport. This would maybe need a mechanism to reset the projection origin once panned a certain distance, in order to avoid huge pixel coordinates. Also, this wouldn't handle zooming -- it would still trigger an expensive full redraw.

Of those options, the third is looking the most attractive to me right now. Anyone got any other ideas to throw in?

@viesturz
Copy link

I noticed you (d3) are clipping all paths to visible extent. Is this necesary? The browser graphics engine does the clipping much more efficently. Also you would not need to re-render the objects after pan.

Starting to guess here, but are you re-projecting points to screen on every pan?

@jfirebaugh
Copy link
Member Author

Currently the paths for line geometries are manually clipped, but areas are not. We actually found that manual clipping was significantly faster than SVG clipping, as it means that you can completely drop the SVG elements for vertices outside the viewport.

iD does re-project and re-render at the end of each pan -- avoiding that is what the third bullet point above is about.

@bhousel
Copy link
Member

bhousel commented Nov 1, 2016

A lot has moved on performance in the last 3 years, and I've done a bunch of performance profiling to prepare for the iD v2 launch, so I'm going to close this and open a new performance ticket.

to summarize:

Pull in d3.geo streaming code and hand-optimize.

d3.geo has some optimizations in d3 v4 (elimination of extra steps and memory copies)

Move path calculation to web-worker.

Path calculation is pretty fast on modern hardware.. The bigger bottlenecks that I see are in osm tile parsing (which can be moved to a web worker) and background imagery polygon testing (a preliminary rbush test before the slower polygon test can speed that up significantly).

Avoid full rerenders on simple pans.

Still a good idea.. We could do extent renders of the newly visible regions.

@bhousel bhousel closed this as completed Nov 1, 2016
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

3 participants