I'm implementing a basic interactive map with some data placed on top of the openstreetmap tiles. The code is very similar to a classic d3.geo.tile example: http://bl.ocks.org/mbostock/5342063
All seems to be working perfectly except one thing: the tiles flicker during zooming and panning. This effect is also observed in the original example and all other use cases of d3.geo.tile I came across so far. This UX bug takes place because the browser is not always able to download the tiles instantly. Surprisingly, even after a certain tile has loaded, its re-appearing is not guaranteed to be instant – flickering does re-occur from time to time.
Slippy map libraries like Leaflet try to compensate flickering by showing cached tiles from the previous zoom levels until the requested ones are ready. To my mind, it would be nice if something similar could be done for d3.geo.tile too.
I tried to play with image.exit()
with the idea that previously shown tiles can be potentially kept on the screen for a bit of time while the new tiles are being loaded. But unfortunately, nothing worked.
Could anyone please suggest a solution to this issue? Smooth D3 maps that don't flicker is something the World deserves in 2016! :–)
UPD
It turns out that making tile url a bit less random partially solves the problem (less flickering occurs when a certain view is revisited):
// before
image.enter().append("image")
.attr("xlink:href", function(d) { return "http://" + ["a", "b", "c"][Math.random() * 3 | 0] + ".tile.openstreetmap.org/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; })
// after
image.enter().append("image")
.attr("xlink:href", function(d) { return "http://" + ["a", "b", "c"][ (d[0] + d[1] + d[2]) % 3 ] + ".tile.openstreetmap.org/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; })
However, this does not solve the problem as a whole.