mapbox / mapbox/mapbox-gl-js

Break up tight coupling between worker and rendering logic and state

Open
#8,311 0 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

performance :zap: refactoring :building_construction:
Dominant language
TypeScript
Stars
12.4k
Forks
2.4k
PR merge metrics
No merged PRs in 30d

Description

Historically, most internal GL JS classes had mixed responsibilities, doing both worker and main thread work and sharing tons of state in between. #5143 removed a lot of serialization boilerplate to make it easier to transfer class instances, but also made the situation harder to control — internal state is now shared between threads implicitly and we haven't really paid close attention to how much of it is necessary to share. There were targeted fixes for the worst bottlenecks (see PRs linked in #7011), but the general problem remains — deserialization on the main thread still takes noticeable CPU time (some of it not shown in profiles because JSON structured cloning with postMessage isn't attributed explicitly).

Additionally, the logic is so tangled now that makes it very hard to understand which of it happens on the main thread, which is on the worker side, and which should be shared intentionally. This contributes to the worker bundle being almost as big as the main thread one, increasing time-to-first-render.

So let's discuss what we could do to address this. I think that since our goal is to eventually minimize logic and state sharing and tight coupling between threads, we should:

  • Revert back to explicit serialization.
  • Switch to raw buffer transfer instead of class instances where possible.
  • Start breaking up various classes like layer buckets into separate ones (render-side and worker-side).

The clearer and more explicit the separation between render-side and worker-side logic, and between shared, temporary and persistent state, the better.

I'm not sure how this correlates with GL Native codebase (especially given that there are considerable architectural differences) (cc @kkaefer), but we've accumulated a lot of technical debt on this front in GL JS and I'd love to see if we could address it this year.

cc @mapbox/gl-js

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The issue names no files, tests, or entry points. Start by mapping the worker/main-thread classes, shared state, and serialization paths in GL JS; done would require an agreed plan and implementation that makes thread boundaries and intentional state sharing explicit.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
computer-graphics, frontend, performance, web-dev
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.