1

I am using Leaflet and Angular (with @asymmetrik/ngx-leaflet ^14.0.1 and leaflet ^1.9.2) and I have an issue with custom marker icons.

On the map, I have approximately 200-400 markers, which are "dynamic" and update each 15 s. (representing vehicles on the map). When the user clicks on the marker, a new icon is set to let the user know, what vehicle is selected. There are only 3 types of selected icon/marker.

When users click on the marker, I see it in Google Chrome Dev. Tools network tab that this image (icon) is loaded, which is fine then I click again, and nothing is shown in the network tab, because the image was cached, which is also fine. But when I click again on the same marker (same icon, therefore same image) after like 10 s., which was already cached, I see that it's loaded again in the network tab. And this is causing problems because there is always a small lag when loading images from the network (and also on slower devices/slower internet speed this will produce blank spots for a while).

I tried to do something like "asset warmup" where I preloaded these three images right after the map is ready, but the loading of the images/icons is still there after approx. 10 s. after warmup. Here is the asset warmup code

  private warmMarkerAssets(): void {
    const selectedMarkerIcons = ["bus/selected_bus.png", "train/selected_train.png", "trolleybus/selected_trolleybus.png"]
    selectedMarkerIcons.forEach((iconPath) => {
      const tempMarker = marker(
        latLng(0, 0),
        { icon: icon({
          iconUrl: this.assetMarkerPath + iconPath,
          iconSize: [40, 40],
          iconAnchor: [20, 20],
        })}
      )
      this.map.addLayer(tempMarker)
      this.map.removeLayer(tempMarker)
    })
  }

Do you have any advice on how to solve this or maybe you already encountered this issue before?

Thanks a lot

Petr Jelínek
  • 1,259
  • 1
  • 18
  • 36
  • Smells like a short [`max-age`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#response_directives) cache control directive on your images by your server. When you inspect your network request, what directives do you get in the response? – ghybs Jan 01 '23 at 19:48
  • @ghybs On the localhost, there is no cache-control header in the response, but on the UAT I am getting these - https://snipboard.io/NltbHp.jpg – Petr Jelínek Jan 01 '23 at 22:04

1 Answers1

1

There does not seem to be any obvious issue with cache control from your screenshot.

it's loaded again in the network tab

Even when served from cache, a "request" may appear in browser network tab, see Check whether network response is coming from server or Chrome cache

Finally, also make sure the Dev Tools "disable cache" option is unchecked.

If you still have actual server requests, then it would require much more detailed investigation, which may be impractical here, unless you are able to share a live reproduction example.

But a quite easy workaround would be to serve your static image as Data URL (with Base64 encoding), at least for the ones that appear on click. This should get rid entirely of any network request for these resources.

Note that if you have a few hundreds of Markers permanently displayed with 1 image, you may prefer keeping that image the normal way, as Data URL/Base64 performs worse when displayed simultaneously so many times, see Leaflet/Leaflet#4968.


BTW, as for "warmup" (preloading image asset content), there is no need to build a Leaflet Marker. See e.g. Preloading images with JavaScript

ghybs
  • 47,565
  • 6
  • 74
  • 99
  • Using Data URL solved the issue, thanks a lot for your help! – Petr Jelínek Jan 02 '23 at 10:38
  • Also, please, just 2 following questions: 1. I can still see in the network tab requests for the image, but this is to the data URL, when I see the "size" column, there is a "memory cache". Is this expected behavior? I thought I won´t see any request for the data URL at all. 2. Final build bundle size increased by 400 kB when using the data URL for images, is this normal? I used only 3 images as data URLs, rest is as normal images served from the assets folder. Thanks a lot – Petr Jelínek Jan 02 '23 at 12:13
  • 1
    "_1. I can still see in the network tab requests for the image, but this is to the data URL_": seems as expected indeed, see https://developer.chrome.com/docs/devtools/network/reference/#hide_data_urls – ghybs Jan 02 '23 at 14:43
  • 1
    "_2. Final build bundle size increased by 400 kB when using the data URL for images_": this is expected as well, because your images content is now inlined within your code, instead of being served as a separate file. The extra size obviously depends on your images complexity. Note that Base64 encoding is usually worse in size than optimized jpg/png, but the size increase is usually mitigated by gzip. And you save the overhead of extra network requests. – ghybs Jan 02 '23 at 14:46
  • Thank you very much, you have been very helpful! – Petr Jelínek Jan 02 '23 at 16:45