question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TileLayer method to swap tiles while minimising flicker

See original GitHub issue

Is your feature request related to a problem? Please describe. Sometimes want to cause the tiles to update, but .redraw() causes all tiles to be removed, and readded. This is undesirable, as causes a very visible flicker to the user, they see all the content disappearing, only to be re added slightly layer. Its made worse because new tiles loaded can ‘animate’ (think 200ms opacity animation)- when they appear. (so even if in browser cache, there is still a delay!)

Describe the solution you’d like Would like to be able to trigger an update of the tile, and for the new tiles to seamlessly replace the old ones.

  1. Firstly by only replacing the the image once the new tile is retrieved from server. (so swap can be quick!)
  2. Not animating the tile replacement, as it’s a swap/update, not a new layer. (or at least if animating, be a ‘cross-fade’. Not a 0-100% opacity animation. )

I think a .refresh() method for TileLayer will do it. So if using a ‘callback’ in the URL template, the callback will be reevaluated. Or can call .setURL(url, false) to prevent the automatic redraw, and call .refresh() instead.

This new would simply loop through all the visible tiles, reevaluate the url template, if changed load the new tile in background, and then swap it with old visible tile. Making sure to not trigger the opacity animation.

Describe alternatives you’ve considered

I have a working implementation that uses jQuery (for the lazy) to loop through the actual <img> in the map and updating the .src attribute directly! Does two extra things,

  1. first loads the tile in a Image Object, and only updates the actual <img> after loading. (so the swap happens when the new tile is already in browser cache!)
  2. temporarily disables map animation. I can’t figure out how to update the .src on the without its onload event firing, which triggers the animation!)

Additional context

Can see demo here: https://www.geograph.org/leaflet/viewpoint.php#17/53.22078/-4.16515 Toggle on the ‘Subject Dots’ layer, the ‘View’ layers (if visible are ‘redrawn’) The view layers are available in both ‘purple marker’ or ‘purple marker + line’ the line is only on if ‘Dots’ layer enabled.

For comparison, a version just using native redraw() method https://www.geograph.org/leaflet/viewpoint-redraw.php#17/53.22078/-4.16515 see if togging Dots, can see all the purple markers disappear, and then reappear. Even if the tile is in browser cache.

And the relevant code: https://gist.github.com/barryhunter/437b661faa92174eb45a9f578fec4512

Will give it a go as new method in https://github.com/Leaflet/Leaflet/blob/master/src/layer/tile/TileLayer.js but thought should open here first to see if anyone has any ideas.

Saw https://github.com/Leaflet/Leaflet/issues/6158 but that is about preventing flicker when not updating the tile, I want to prevent flicker when updating tile URL!

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:5
  • Comments:27 (11 by maintainers)

github_iconTop GitHub Comments

2reactions
barryhuntercommented, Oct 20, 2020

Oh, sorry about the demo, a upstream dependency (unrelated to the actual problem) has moved! Will update that.

In theory would just include the code, https://gist.github.com/barryhunter/e42f0c4756e34d5d07db4a170c7ec680

then

var timeWVTile = L.tileLayer2(timeWV, ...

ie tileLayer2 ‘extends’ the normal tileLayer, and adds functions, but otherwise its use is the same.

timeWVTile.setUrl("http....", true); 
timeWVTile.refresh();

The added true on the setUrl is to disable the internal redraw function. Don’t want that, as its the one that has the ‘flicker’.

But then you need to explicitly call the (new) refresh method, which does the (hopefully) graceful reload of tiles.

… do remember this still a ‘bodge’. The refresh method messes with the main maps ‘Animated’ setting (because couldnt figure how to disable the animaton only on the specific tiles (or even just the tilelayer)) - if call refresh too quickly, it can end up that animation remains turned off completely!

1reaction
martinRenoucommented, Jan 31, 2020

I am surprised this does not have more attention. I feel like it’s an important problem to fix.

@barryhunter is your fix still up to date? Did you make it a plugin?

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to update TileOverlay without a flicker? - Stack Overflow
A fairly good solution would be to separate tile downloading and caching from TileProvider. This way you can fully control when they are...
Read more >
TileLayer - deck.gl
This approach minimizes the visual flashing due to missing content. 'no-overlap' : Avoid showing overlapping tiles when backfilling with cached content. This is ......
Read more >
Schluter®-DITRA Installation Handbook 2017
DITRA will forever change the way you lay tile. Ceramic and stone tiles are durable, easy to maintain, and hygienic, representing the ideal...
Read more >
How to refresh a layer in leaflet.js without flickering
The overlay layer has some code to make sure the tiles are not cached, without this the image doesn't change: var dynLayer =...
Read more >
deck.gl | What's New
New getData method in CARTO 3 to support other deck.gl layers. ... TileLayer may continue to display tiles when underzoomed. See the new...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found