Skip to content

Conversation

@samithahansaka
Copy link

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
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
Author

happy to collaborate for a good cause.

@samithahansaka
Copy link
Author

@usefulthink any update on this?

@usefulthink
Copy link
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
Author

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

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