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

Efficiently apply style changes by diff-ing new and old styles (i.e. smartSetStyle) #1989

Closed
lucaswoj opened this issue Jan 25, 2016 · 10 comments

Comments

@lucaswoj
Copy link
Contributor

Continuing from #1341 now that constants have been eliminated from the style spec (per #1348 (comment)).

@lucaswoj lucaswoj changed the title Efficiently apply style changes by diff-ing new and old styles Efficiently apply style changes by diff-ing new and old styles (i.e. smartSetStyle) Jan 27, 2016
@lucaswoj
Copy link
Contributor Author

lucaswoj commented Feb 3, 2016

@averas also suggested the inclusion of a map.setStyleLayers API, to skirt the cost of transferring large GeoJSON sources. I think this is a good idea.

@jfirebaugh
Copy link
Contributor

Eh, I'm mildly -1 on map.setStyleLayers. I want the core API to be a set of orthogonal primitives, and we already have a batch API upon which setStyleLayers can be implemented.

@averas
Copy link
Contributor

averas commented Feb 3, 2016

@jfirebaugh Could you review our last 4 posts in #1982 and comment?

This basically stems from the desire to apply a new style without losing all existing sources, especially the expensive ones (large GeoJSON objects).

@averas
Copy link
Contributor

averas commented Feb 3, 2016

I hadn't actually noticed the batch API, and it looks quite neat to make batch changes to the style without replacing the entire style.

Still however, if a smart Map#setStyle() with diff/transition support is implemented I would argue that it will be expensive to use if you're working with large GeoJSON structures, meaning that you will have to fall back on the batch API or the setProperties functions just to avoid the expensive GeoJSON diffing, which would be sad.

@jingsam
Copy link
Contributor

jingsam commented Apr 2, 2016

I am +1 for smartSetSyle(). For this, I can modify the style json and do not operate map directly. smartSetSyle() will make smart diff and apply changes. This is actually what React do. React proves efficient diff is possible. Style json is way much simpler that dom, so I think smartSetSyle() is feasible.

@lucaswoj
Copy link
Contributor Author

lucaswoj commented Jun 9, 2016

I'm envisioning this feature as a unification of the current style mutation batching system and the mapbox-gl-style-spec diff utility built for Studio

cc @tmcw

@jfirebaugh
Copy link
Contributor

Ambitious proposal for implementing this, going the opposite direction from "API as a set of orthogonal individual mutators":

Extract a pure, low-level component whose only mutator is a React-style setState, where the state is style JSON, including camera state as top-level style properties. Notably, this component would not support any of the following:

  • APIs for mutating individual bits of style or camera state.
  • Automatic event bindings for camera movement.
  • Style URLs. (Style loading would be the responsibility of a higher-level component.)
  • Paint classes. (This proposal would obviate most use cases for paint classes; if you really need them, preprocess the style instead.)

Internally, the component will need to maintain loaded data (such as tiles) and derived state (such as buffers and computed refs). To allow efficient, maximal reuse of this data and efficient, minimal recomputation of derived state, the component would require that the object passed to setState be immutable, such that it need not ever be copied and fast equality comparisons at any level of the object hierarchy are possible. (I imagine that internally, the first line of optimization would be skipping work based on object identity comparison, and the second would be based on diffing objects and responding with minimal updates. Not coincidentally, this is analogous to the two main React optimization pathways: shouldComponentUpdate shortcuts and virtual DOM diffs.)

Provide additional modules for:

  • A canonical implementation of an immutable style API. Provides a Style class with addLayer, setPaintProperty, and so on, but they all return new objects rather than mutating the caller.
  • Camera animation.
  • Camera event bindings.

Provide a traditional Map API as a combination of these modules. But Mapbox Studio, React applications/libraries, and other use cases desiring "smart setStyle" would use the lower level modules.

@lucaswoj
Copy link
Contributor Author

I'm strongly in favor of a React-like declarative setStyle interface as proposed in #1989 (comment) and https://github.com/mapbox/gl-internal/issues/428#issuecomment-223448114 👍

@anandthakker
Copy link
Contributor

Haven't thought this all the way through, but this might also provide a nice little boost for updating worker layer info by sending just the diff over the channel

@jfirebaugh
Copy link
Contributor

Implemented in #3621!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants