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

Reduce worker payload #7124

Merged
merged 4 commits into from
Aug 14, 2018
Merged

Reduce worker payload #7124

merged 4 commits into from
Aug 14, 2018

Conversation

mourner
Copy link
Member

@mourner mourner commented Aug 14, 2018

Reduces the size of the JSON (excluding transferred arrays) that gets sent from the worker to the main thread, reducing lags during tile loading (in theory). Partially addresses #7011.

For a dense z11 Mapbox Streets v10 tile in DC, the payload is reduced by ~44%. For the expressions-based Basic style, the reduction is 39%.

See individual commits. The first one has the biggest impact (~28%) — it converts serialized form from {name: 'Object', properties: {foo: 'bar'}} to {foo: 'bar} for simple objects and {$name: 'Foo', foo: 'bar'} for both registered classes and custom-serialized ones.

Launch Checklist

  • briefly describe the changes in this PR
  • write tests for all new functionality
  • document any changes to public APIs
  • post benchmark scores
  • manually test the debug page

Leads to further 10% improvement of worker payload.
@@ -386,7 +394,7 @@ export default class ProgramConfiguration {
const useIntegerZoom = value.property.useIntegerZoom;

if (value.value.kind === 'constant') {
self.binders[property] = new ConstantBinder(value.value, name, type);
self.binders[property] = new ConstantBinder(value.value.value, name, type);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one's weird — I guess this was a buggy code in an unused code path, since this doesn't break any tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And flow isn't helping us here because ConstantBinder is deducing the type from that first argument? 😕

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess it's because of flow templating (ConstantBinder<T>) — I'm not fully sure how it works (@jfirebaugh may know better) but looks like if there's a template or an any in Flow, you can basically do anything in the code the touches those places without any type safety.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! The problem is we're ignoring the template type in places that would have caught this, e.g. binders is typed as {[string]: Binder<any>} and UniformBindings is typed as {[string]: Uniform<any>}. We'd need more sophisticated per-layer aggregate types like in native to catch this.

This bug manifests when changing a constant property to a data-driven property, in the period before the new layout is completed. We have an integration test for this case (runtime-styling/paint-property-literal-to-property-expression), and I can see the wrong type getting passed into gl.uniform1f, but I guess headless-gl doesn't do strict enough type checking to catch this.

@mourner mourner changed the title Reduce worker payload by 40% Reduce worker payload by 44% Aug 14, 2018
@mourner
Copy link
Member Author

mourner commented Aug 14, 2018

image

image

@mourner mourner changed the title Reduce worker payload by 44% Reduce worker payload Aug 14, 2018
const ab = grid.toArrayBuffer();
type SerializedGrid = { buffer: ArrayBuffer };

Grid.serialize = function serializeGrid(grid: Grid, transferables?: Array<Transferable>): SerializedGrid {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm missing something... what was the JSON savings in changing from serializing as an ArrayBuffer to serializing as a SerializedGrid?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you serialize just the ArrayBuffer which is transferred, any custom properties on it (in this case $name) don't survive the transfer. Before the PR we implicitly transferred in a wrapper ({name: 'Grid', properties: buffer}), and now we explicitly transfer as {$name: 'Grid', buffer}. I'm now throwing an error is serialize in case the serialized object is fully transferred just so that we don't trip up on this in future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah got it, thanks.

Copy link
Contributor

@ChrisLoer ChrisLoer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@mourner mourner merged commit 3d879b2 into master Aug 14, 2018
@mourner mourner deleted the reduce-worker-payload branch August 14, 2018 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants