Skip to content

feat: add Web Worker support for marker clustering - #891

Merged
usefulthink merged 3 commits into
visgl:mainfrom
samithahansaka:feature/worker-clustering
Jan 26, 2026
Merged

feat: add Web Worker support for marker clustering#891
usefulthink merged 3 commits into
visgl:mainfrom
samithahansaka:feature/worker-clustering

Conversation

@samithahansaka

Copy link
Copy Markdown
Contributor

Summary

  • Adds useSuperclusterWorker hook for offloading clustering to Web Worker
  • Adds useMapViewport hook for tracking map bounds and zoom
  • Adds worker-marker-clustering example demonstrating 10k+ markers

Problem

Addresses #526 - clustering with large datasets (7,500+ markers) blocks the main thread, causing UI freezes up to 17 seconds.

Solution

Moves Supercluster operations to a Web Worker, keeping the main thread responsive regardless of dataset size.

Changes

  • src/hooks/use-supercluster-worker.ts - New hook
  • src/hooks/use-map-viewport.ts - New hook
  • src/index.ts - Export new hooks
  • examples/worker-marker-clustering/ - Full working example

  - Add useSuperclusterWorker hook for offloading clustering to Web Worker
  - Add useMapViewport hook for tracking map bounds and zoom
  - Add worker-marker-clustering example demonstrating 10k+ markers
  - Prevents main thread blocking for large datasets (Discussion visgl#526)
@usefulthink

Copy link
Copy Markdown
Collaborator

I haven't had time to review it, but most importantly: Awesome, thanks a lot for the work!

This is something I wanted to do for a while and never got around to. Looking forward to review and test it tomorrow.

@samithahansaka

Copy link
Copy Markdown
Contributor Author

happy to collaborate for a good cause.

@samithahansaka

Copy link
Copy Markdown
Contributor Author

@usefulthink any update on this?

@usefulthink

Copy link
Copy Markdown
Collaborator

I now had the time to have a quick look, and it's really nicely done, focused on the important parts and all that.

When I ran it locally with npm run start-local, it didn't work out of the box (there seems to be some styles missing – map div has height: 0 initially). But that should be easy to fix. Also we could do a bit polishing by using a reduced map style and things like that. I can look into that if you like me to.

It still feels a bit slow sometimes, since even with clustering it's rendering too many AdvancedMarkerElements (>800) at once. That could be fixed by increasing the clustering radius a bit.

The only thing that would be important to change is to move the two hooks into the examples src directory instead of the main library. I really like the Idea to export a useMapViewport hook, and I would love to add that as a feature, but I'd like to give that another spin first (add things like configurable events (update instantly when the view changes vs. update on idle), debouncing to avoid emitting too many events, ...).

However, we will likely not add the supercluster-specific hook to the library for the time being, since that is a bit too specific to a certain use-case.

Finally, it still has to be added to the examples-page on the website (there's some documentation about that here, but I just noticed that that page is outdated – examples with external dependencies do work completely fine now).

  - Fix map height: 0 issue by adding body/app container styles
  - Increase clustering radius from 80 to 120 to reduce marker count
  - Move useMapViewport and useSuperclusterWorker hooks from library to example
  - Remove hook exports from main library index.ts
  - Update imports in app.tsx to use local hooks
  - Update README with new file structure and usage examples
@samithahansaka

Copy link
Copy Markdown
Contributor Author

@usefulthink updated the pr, could you please have a look and let me know if you want more changes.

@usefulthink usefulthink left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we can merge it like this and do additional PRs to add it to the website and so on.

@usefulthink
usefulthink merged commit dd007c8 into visgl:main Jan 26, 2026
2 checks passed
@usefulthink

Copy link
Copy Markdown
Collaborator

Thanks a lot!

usefulthink pushed a commit that referenced this pull request Aug 12, 2026
`useSuperclusterWorker` and `useMapViewport` were added to `src/hooks`
alongside the worker clustering example by accident in #891. They are not exported from `src/index.ts`, not imported anywhere, so they never reached `dist`. 

Refs #1049
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.

2 participants