fix(examples): reuse the luma.gl device when StrictMode remounts DeckGlOverlay - #668
Merged
Merged
Conversation
…GlOverlay In development, React StrictMode mounts DeckGlOverlay twice, so the interleaved MapboxOverlay creates two Decks on MapLibre's WebGL context back to back. Both attach a luma.gl device concurrently, and in the Zarr examples the second attach threw "WebGL context already attached to device", so nothing rendered. Pass deviceProps._reuseDevices so the second Deck reuses the device instead, as deck.gl already does for devices it creates itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I noticed issues with rendering Zarr-based examples locally. Those same Zarr-based examples work in the published examples online and when built in production mode locally.
It seems that there's a specific interaction between vite, react strict mode, maplibre, and deck.gl.
The below workaround seems to work locally.
Note
This PR description was written by Claude (Claude Code) on behalf of @kylebarron, not by @kylebarron.
Fixes the Zarr examples (
aef-mosaic,dynamical-zarr-ecmwf,nldas-icechunk) rendering nothing undervite dev, with this error:Production builds were never affected.
Cause
StrictMode(development only) mountsDeckGlOverlaytwice. In interleaved mode, each mount makesMapboxOverlaycreate anew Deckon MapLibre's WebGL context. So deck A is created, finalized about 1.5ms later, and replaced by deck B.attachchecks for an existing device, awaits some async work, then creates one, throwing if a device appeared in between. If both checks run before either device exists, deck B throws. B is the deck that survives, so nothing renders._reuseDevices: truewhen it creates its own device (deck.ts#L1469-L1473), with a comment about exactly this, but not when it attaches to an existing context (deck.ts#L434-L440).Fix
DeckGlOverlaynow passesdeviceProps: { _reuseDevices: true }, merged with anydevicePropsthe caller supplies. Deck B then reuses deck A's device instead of throwing. That's safe:Deck.finalize()nor luma'sAnimationLoop.destroy()destroys a device attached to an external context;In production there's normally only one deck, so the flag changes nothing there.
Testing
Checked in Chrome under
vite dev:aef-mosaic,dynamical-zarr-ecmwfandnldas-icechunknow render, with no console errors.land-cover(COG) is unaffected.webgl-device-1instead of throwing.pnpm -r typecheckandpnpm checkpass.🤖 Written by Claude Code