Mapbox-gl-js: Start web worker from static URL on startup

Created on 25 Jan 2018  路  9Comments  路  Source: mapbox/mapbox-gl-js

Issue

Currently, Mapbox GL JS dynamically generates a worker on startup and hosts it in a local window URL. This startup method causes issues with:

  1. Applications that require a worker:src CSP
  2. Mapbox GL startup in iframe sandbox permissions allow-same-origin on IE11, Safari, and Edge browsers.

Possible implementation

  1. Add another build step that browserifies https://github.com/mapbox/mapbox-gl-js/blob/master/src/source/worker.js
  2. Modify https://github.com/mapbox/mapbox-gl-js/blob/master/src/util/browser/web_worker.js so that instead of using WebWorkify, it takes a real URL (by which that browserified worker build will be accessible)

Ideal solution

Ideally, we'd be able to detect CSP on the client and load the same JS file again, with a different entry point. The entry point can be a static worker URL if CSP worker:src is enforced.

cc @kkaefer

Related: https://github.com/mapbox/mapbox-gl-js/issues/6056

api

Most helpful comment

As of #6196, we're now building our bundle using Rollup, and while we're still producing a single bundle that loads the worker via a blob URL, we're much closer to being able to build & load the worker as a separate bundle:

  • The main bundle loads the worker from mapboxgl.workerUrl. By default, this is set to the Blob URL, but we could easily allow it to be overwritten by client code to point to the location of a standalone copy of the worker bundle.
  • The build process already has an intermediate step in which the worker and its dependencies are bundled separately from the main entrypoint. Adding a step to build & distribute a standalone worker.js would be straightforward.

All 9 comments

ideally, we'd be able to detect CSP on the client and load the same JS file again, with a different entry point

@ryanbaumann is this preferable over having a separate worker bundle, per https://github.com/mapbox/mapbox-gl-js/issues/5939?

@anandthakker Either solution should work fine - whether the developer has to build the specific CSP support version, or the browser could make a run-time decision of which web worker initialization source to use.

Quick proof of concept here: https://github.com/mapbox/mapbox-gl-js/tree/blobless, just tries the blob url first, catches the exception and tries again with a (user-provided) network URL instead.

The fact that Safari disallows Blob reads in a sandboxed iframe is a bug: https://bugs.webkit.org/show_bug.cgi?id=170075

I know of one other place that blobs are used in Mapbox GL JS: https://github.com/mapbox/mapbox-gl-js/blob/b5722b900378ba51904a8a1960d560fed991878e/src/util/ajax.js#L141

Presumably we'd need a workaround for that as well.

@jfirebaugh thanks for linking the bug in Safari.

Summarizing what we've tried so far to support Mapbox GL on Safari in a sandboxed iframe:

  1. Load the worker source from a blob URL in an https page.
  2. Load the worker source from a local file.

    • Result - does not work in a sandboxed-iframe environment. Chrome, Firefox, and Safari all throw an error requesting the local resource from null origin. This is the expected behavior in sandboxed iframes with allow-same-origin not enabled.

  3. Load the worker source from a data URI.

Given the three options above, the only option we know of to support Mapbox GL in Safari using an iframe sandbox without the allow-same-origin flag is to fix the Blob read URL bug in Safari https://bugs.webkit.org/show_bug.cgi?id=170075

As of #6196, we're now building our bundle using Rollup, and while we're still producing a single bundle that loads the worker via a blob URL, we're much closer to being able to build & load the worker as a separate bundle:

  • The main bundle loads the worker from mapboxgl.workerUrl. By default, this is set to the Blob URL, but we could easily allow it to be overwritten by client code to point to the location of a standalone copy of the worker bundle.
  • The build process already has an intermediate step in which the worker and its dependencies are bundled separately from the main entrypoint. Adding a step to build & distribute a standalone worker.js would be straightforward.

@anandthakker fwiw, this is an important issue for us, now that Kibana will start shipping with a mapbox-gl dependency. Are there any plans to bump up this issue and add this option to future versions of mapbox-gl? thanks,

@thomasneirynck - thanks for raising this issue to us. We'll add this to our planning and get back to you when we have a timeline.

Looked at this again and turns out most of the groundwork for this was already laid out when we switched to Rollup for bundling. So I JFDI: #8044

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stevage picture stevage  路  3Comments

jfirebaugh picture jfirebaugh  路  3Comments

shotor picture shotor  路  3Comments

aderaaij picture aderaaij  路  3Comments

PBrockmann picture PBrockmann  路  3Comments