maplibre-gl-js icon indicating copy to clipboard operation
maplibre-gl-js copied to clipboard

Map sometimes renders custom images or font characters instead of basemap tiles

Open gabeschine opened this issue 1 year ago • 21 comments

We have recently seen very intermittent, odd behavior of the base map layer showing up as a set of our internal icons tiled across the map or a set of letters tiled across the map.

In one case, it appears a base map layer has partially loaded with these icons overlayed on top of it.

Here is my best attempt at a text description of the symptoms. See the video below (https://github.com/maplibre/maplibre-gl-js/issues/2811#issuecomment-2249318129) for a great example.

  • Light gray (“white”) basemap tiles, often with other non-basemap layers still visible
    • In particular, GeoJSON source layers don’t seem to be affected
  • Sometimes basemap streets, some place names, or highway badges are still visible
  • Sometimes basemap tiles are replaced by font glyph texture
  • Sometimes basemap tiles are replaced by potpacked user-added icons texture (from calls to Map.addImage())
  • Symptoms above can change when panning around the map or zooming in/out
    • Results in flickering/flashing of map tiles
    • A given tile can display any of the above incorrect textures
  • A given symptom seems to be different for every map tile, although the flickering behavior will show within a single integer zoom level while zooming
    • Crossing a zoom level seems to “change the symptom”: may go from glyph texture at one zoom level to gray, or user-added icons texture, at the next zoom level
  • Trigger seems to happen right after bringing the app into focus again after it’s been running in the background. However, it has happened quickly after app launch
  • Have confirmed instances with the exact same symptoms (including video evidence/photos on some) for:
    • iPhone app (Capacitor which has a WebView in it aka. Safari) (countless users)
    • iPhone Safari Mobile (a few users)
    • Windows running Chrome (2 users)
    • Windows running Firefox (1 user)
  • It seems as though the 2d canvas context that contains the style sprites is cleared when this bug happens, and otherwise appears to be populated. Not knowing the architecture, I’m not sure if this is unexpected behavior or normal
  • A little different every time

** Helpful images / videos **

Screenshot 2023-06-27 at 4 50 04 PM

And in the second, it appears to just be the set of english characters tiled. Screenshot 2023-06-27 at 4 50 31 PM

image image image image

I have caught the bug twice on a dev device, but did not catch the transition from working -> broken while attached and using developer tools. Once the map experience is broken, there are no console logs.

I am using:

maplibre-gl: 3.1.0 and react-map-gl: ^7.0.25

Originally posted by @davidemerritt in https://github.com/maplibre/maplibre-gl-js/discussions/2738

gabeschine avatar Jul 06 '23 17:07 gabeschine

I would start and try to reproduce this without the react wrapper. Generally speaking, if you can't create a jsbin that reproduces this it will be almost impossible to help you...

HarelM avatar Jul 06 '23 20:07 HarelM

Just commenting to note that we're seeing this also. It's occurring rarely and we don't have reproduction steps yet. But I'll post here if we figure anything out.

zta6 avatar Oct 04 '23 15:10 zta6

I think I also saw it now:

wipfli avatar Jan 31 '24 10:01 wipfli

markup_1000031133 (1)

wipfli avatar Jan 31 '24 10:01 wipfli

I'm also seeing this - very similar with the font or icons being patterned across the base maps.

davidemerritt avatar Jun 19 '24 17:06 davidemerritt

We're having issues with this as well. We're seeing icons, fonts and neighboring tiles being patterned. Seems to mostly happen on iOS. We're not using the React wrapper, but similarly don't have solid steps to reproduce it...

Update: We've also seen this once on Chrome

bulbwheatie avatar Jun 26 '24 01:06 bulbwheatie

We’re willing to pay a contractor to fix this bug for us. If you’re interested please reach out to me at [email protected] and we can talk about the details!

zta6 avatar Jul 01 '24 16:07 zta6

Adding an interesting video capture of the bug in our application:

https://github.com/user-attachments/assets/42ce41a8-b403-41b2-b611-17db9d8cd500

davidemerritt avatar Jul 25 '24 03:07 davidemerritt

@wipfli , did you use react-map-gl here? are you able to repro it with a codepen?

birkskyum avatar Jul 31 '24 14:07 birkskyum

@birkskyum - we have been working with CalTopo behind the scenes to try and diagnose this. They are not using react-map-gl. Would it be useful to see how they are handling the Map instance's lifecycle?

In my experience, this issue is triggered by some lifecycle event that happens when the page is re-focused after being in the background for some period of time (could be short, could be long - no correlation I could see).

gabeschine avatar Jul 31 '24 14:07 gabeschine

I was using https://onthegomap.com in Chrome on Android. @msbarry do you use react-map-gl for onthegomap?

wipfli avatar Jul 31 '24 18:07 wipfli

@msbarry do you use react-map-gl for onthegomap?

It's not react-map-gl, just a custom integration of maplibre into react, basically react just sets up a dom node and maplibre renders into that like it would be on a non-react page.

msbarry avatar Jul 31 '24 23:07 msbarry

An interesting thing has happened the two times I have been able to attach the Safari devtools to the remote WebKit instance running on the iPhone. In both cases, I was not able to catch the transition from "working" to "broken", but I was able to poke around. What I noticed was that there are two canvases (one 2d, one 3d/webgl) that are known to the web container.

In the broken state, the 2d canvas is blank:

image

While when things are running correctly, that same canvas contains the style's sprites:

image

I have so far found where this canvas is created (browser.getImageCanvasContext()), but I cannot find where the canvas' content is purposefully cleared. I also don't know WebKit well enough to know when/why it would clear a canvas' content. I suppose it's possible that if somehow bad sprites data was downloaded, that could result in what appears to be a cleared canvas, by attempting to write said bad image data and it not working.

Just an interesting tidbit that will hopefully result in some insight from one of the maplibre contributors :).

EDIT: I just noticed after posting that the dimensions are just a little different (2048x1020 vs 2048x1014). That's odd because nothing about the style has changed in our app for a long time.

gabeschine avatar Aug 01 '24 20:08 gabeschine

I think there were a few iteration regarding getting an image bitmap/pixel value due to all kinds of security limitations (mainly firefox) and browsers limitations (mainly safari). The code in utils, browser, offscreen canvas is related to it, which might explain why you see this mostly in safari.

HarelM avatar Aug 02 '24 04:08 HarelM

@wipfli is your app also a react js app?

Does the statement about when this bug is triggered for us (on app resume from suspend / background) also your experience? @wipfli @bulbwheatie @msbarry?

Interestingly, we've had a couple reports of the same event "healing" the broken state. Usually, people force-quit the app - but if you don't, it can fix itself. I've observed this as well.

gabeschine avatar Aug 02 '24 18:08 gabeschine

Here are two more videos. https://github.com/user-attachments/assets/e8021a74-d917-4cbb-aea7-70711d6a4160

https://github.com/user-attachments/assets/8cd48d07-7f33-42b9-b8af-3591be23367d

gabeschine avatar Aug 05 '24 14:08 gabeschine

A new variation reported by one of our users. IMG_9421

Also the behavior described by Gabe is consistent with what we've been seeing as well:

In my experience, this issue is triggered by some lifecycle event that happens when the page is re-focused after being in the background for some period of time (could be short, could be long - no correlation I could see).

bulbwheatie avatar Aug 05 '24 15:08 bulbwheatie