Hacker News new | comments | ask | show | jobs | submit login
Pigeon Maps – Maps in React with no external dependencies (mariusandra.github.io)
310 points by mariusandra 4 months ago | hide | past | web | favorite | 55 comments

That was like Running maps locally. My first guess was it must be serving from some super local cdn cache. So tried looking for the data serving domain. It feels even more awesome after looking at latency number.

This is loading all data from maps.wikimedia.org.

Tracing route to maps.wikimedia.org [] over a maximum of 30 hops:

  1    <1 ms     3 ms     2 ms
  2     7 ms     6 ms     6 ms  abts-north-static- []
  3     8 ms     5 ms     9 ms
  4     7 ms    10 ms     6 ms
  5    51 ms    51 ms    65 ms
  6    47 ms    50 ms    47 ms
  7    73 ms    73 ms    72 ms
  8    73 ms    73 ms    72 ms  14907.sgw.equinix.com []
  9    79 ms    79 ms    93 ms  upload-lb.eqsin.wikimedia.org [] 

Now Google Maps seems to be serving all data from root domain www.google.co.in. So here we go.

Tracing route to www.google.co.in [] over a maximum of 30 hops:

  1    <1 ms     1 ms     1 ms
  2     8 ms     5 ms     6 ms  abts-north-static- []
  3     6 ms     6 ms     5 ms
  4    10 ms     7 ms     6 ms
  5    42 ms    44 ms    42 ms
  6     8 ms     7 ms    14 ms
  7     8 ms     7 ms     7 ms  del03s16-in-f3.1e100.net []

So even after getting additional latency penalty of ~60ms, it still feels snappier! Imaging it could be even more faster with local CDN nodes. 60ms = ~3 Frames on 60Hz Monitor refresh rate.

Especially with a local image cache!

I just want to express how snappy this feels. It really does feel so much faster than other solutions. Good work!

It's actually faster than running OpenMapTiles locally on my old development machine was! Excellent work.

This is using prerendered and cdn-cached PNG files. openmaptiles usually uses pbf vector tiles, which needs to be rendered in js.

It is to be expected that this is quicker on any halfway decent internet connection.

Personally, I've been really annoyed with the slow, unresponsive Google Maps on my phone when my reception gets a little bad. I'd definitely like to try comparing this against Google Maps with the same poor connection (packet loss). The 25kb compared to 200kb for Google Maps makes a huge difference! Actual rendering speed seems a lot faster as well, which is another huge plus on my dated smartphone.

I'm not a web purist who looks for the most minimal libraries and works overtime to minimize my JS and HTML and CSS, but there is certainly something to be said about the old mobile web vs the new mobile web. I remember in 2006/2007 streaming YouTube videos on an EVDO mobile connection. Meanwhile these days unless my phone says LTE, Facebook won't even load my news feed.

Google Maps seems to be the worst, even on my recent Macbook Pro and 60mbps Internet, scrolling feels like I'm pushing heavy furniture across an unfinished concrete floor. I can almost feel it scratching and scraping and resisting every attempt to pan left or right.

In the era of "mobile first" and PWAs and all that, how is it that we require a rock solid Internet connection and a super fast processor with gobs of RAM just to get a shitty experience on the web? And if either one of those drops in the slightest, you're locked out solid.

amen. the real world is being pretty stubborn about flakey and slow internet, despite what those living in the SV microcosm experience...

I use Nokia HERE WeGo. GPS navigation, and you can download the whole country you live in and store it offline. Stored as vector data so it isn't too huge. No mobile data connection needed, wherever you go.

What are the cost implications for using this (in terms of the backend maps providers)? I looked at MapBox's pricing, for example. Does that still apply when using this? Presumably so but I find the distinctions a bit confusing in the JS maps world.

This looks like really great work.

Completely unrelated and irrelevant observation though... I found the use of buttons to mimic checkboxes feels a bit odd to me.

Also, Github repo link for those who want to see the source or star it, since there is no link on the demo right now: https://github.com/mariusandra/pigeon-maps

Thanks! I added a link to the github page on the demo.

And for the checkbox buttons... oh well :D

I thought that was a rather clever lightweight toggle button for a proof-of-concept!

A lot of people seem to be saying this is incredibly fast, but for me it loads only about as fast as android Google maps and the pinch-zoom/pan are incredibly choppy with massive input lag.

Yeah, on iOS it’s noticeably slower than {Google,Apple,OSM} and significantly choppier than LeafletJS even without the buggy gesture support.

Unfortunately I have no access to an iDevice for the remainder of the week as I'm traveling for work. If anyone can help debug this and perhaps even submit PRs, it would be greatly appreciated!

I believe the input lag may be addressed by setting either width=device-width or user-scalable=no on the viewport, or using the CSS touch-action property.

It's actually beautifully fast on my iPhone X. Will definitely research the cost of replacing Leaflet with this library. Thank you!

For me this was happening on a mid-range android phone using Firefox. It's fine in chrome.

Same here. Android/FF. But still a bit snappier than Google Maps.

How is it even possible to be that fast? What's the secret sauce?

Isn’t React an external dependency with a host of dependencies of its own needed to build? Or does this mean it only depends on React and nothing else?

Kudos, like leaflet for react! Does it support vector tiles?

Unfortunately not. Currently vector tiles are outside my personal scope for the project, but I of course welcome PRs.

Does it support drawing poly lines?

How did I miss this a week ago? Looks great!

I recently whipped up a quick hobby project where I'm displaying a map on an old kindle by running wkhtmltoimage on a server and displaying the png. It's got a giant delay in responding with a lot of it due to Mapbox initialization time.

Does anyone know if it is ok to deploy tiles used by this library inside intranet, in sites without internet access? If so, what is the recommended way of doing it?

Tiles are generally just static PNG images. I serve a bunch using nginx and also on CloudFlare CDN. It's as easy as making the folder containing the tiles available on a webserver. I use QGIS/gdal to generate the tiles.

It was super smooth at first but really slowed down after moving the map, to the point where I had to force close the tab.

Very quick, but the demo isn't showing attribution for at least some of the map tiles correctly.

Hi, I added attribution to the Mapbox maps. Please reply if any of the others are wrong as well.

Stamen requires attribution and license information mentioned, I believe Wikimedia requires attribution with a link to details.

Demo updated, thanks!

Is there a description about how you built this?

Well, there's the github commit history, that sort of answers the question, no? :D

Otherwise no, there is no write up of the process. I might do one some day, thanks for the idea.

You should totally do a blog post! You could also volunteer to present on it at your local JS or React meetup (or the closest city that has one). Maybe post a video of your talk?

please make a write up or video too I'm curious how this was made

nice, this is one of those things you clone immediately

speaking of which, why do people debate about whether forks on github are persistent even when the author removes their copy, when you can always clone either way, since that keeps a copy on your system and you still have the code

There’s not much point to use react for something like this. If you know the map canvas size and tile size of your tiles, you simply need to initialize that many images in your container. That only ever changes when the map canvas size changes or the tile size changes. Pans and zooms of the map only change the src of the images at that point.

React is already used for tons of apps, some of those apps need to display maps and it makes perfect sense to use something in your existing framework.

Exactly! This project is for apps that already use React and need to add maps.

Alternatively, you can try preact [1] or inferno [2] and for a few KB more you have something that is still smaller than Google Maps or Leaflet.

Of course if you need more advanced features and geometric calculations the size can go up considerably. Leaflet and Google Maps provide that out of the box. Pigeon-maps doesn't.

[1] https://preactjs.com/ [2] https://infernojs.org/

Leaflet out of the box implements vector tiles, different map projections, has a full layer API, full support for mobile, etc. so it's not a direct 1:1 comparison with your project which is implementing a basic mercator raster tile layer.

You can also strip Leaflet down to just the raster tile layer stuff and as it doesn't need react or preact or inferno it will be lighter weight than your solution, and still uses the fundamental underlying display mechanism of image tags.

If you need support for all that leaflet provides, go for leaflet. If the feature set of pigeon-maps is enough for your needs and you already use react, feel free to go for it instead.

I have never claimed it to match the features of Leaflet while being lighter. It's lighter exactly because it doesn't. Offloading a lot of DOM work to React makes it even lighter.

Edit: to correct one point, pigeon-maps does support mobile.

>> Offloading a lot of DOM work to React makes it even lighter.

What exactly does this mean? The only thing that ever changes, as I mentioned, is the src of the image tags in these kinds of tiled maps. How do you get better performance for updating the src attributes in a grid of images of constant size (256x256 tiles or whatever) other than img.src = ''? That's literally the only DOM manipulation being done, there is no "magic".

Also you can reduce a lot of your mouse event handling stuff down to a single "reactive" (haha) callback by doing something like this: https://github.com/mikolalysenko/mouse-event. Instead of binding a bunch of different handlers, the browser's mouse events API is still bizarre after all these years. Should just be a single event that gets sent the state of control input.

> What exactly does this mean? The only thing that ever changes, as I mentioned, is the src of the image tags in these kinds of tiled maps.

What about markers?

I think you are looking at this a bit backwards it seems to be a tool used in existing React apps to display maps. Not a tool to display maps that uses React.

It's at least 2x that number, if you want to have a nice fade transition. More if you want to buffer the extents.

And that's not to mention the things being displayed on the map, like popups, markers, or polygons. Which React's model helps a lot with.

You can do that with a CSS transition via a class you apply to the element when you change its src and/or have another layer of tiles that you alternate. I was just pointing out the fact that the only thing ever changes here is the src of the image tags of the tiles, the elements always remain constant. So using React is way overkill for what is essentially a static grid of image tags.

This library is made for sites that already use React.

I noticed this also supports Inferno. To the author: what's your preference?

I only use React. The Inferno support was added 2 years ago when an issue requested it, as I was evaluating Inferno support myself at the time. Since then I haven't done anything with it.

first impression was epic but there's something wobbly with the interaction or is it just me? sometimes scrolling goes to hell and same for panning

Could you describe what you experienced in more details? Scrolling with a mouse? Trackpad? Touch? Could you quantify "goes to hell"? The more details the better of course. Thanks! :)

Seems really lightweight and fast!

Wow, this is fast!

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact